CLAUDE.md Anti-Patterns: 12 Productivity Killers
Avoid the most common CLAUDE.md mistakes that frustrate developers and waste time. Learn the troubleshooting techniques that get Claude Code back on track.
A bad CLAUDE.md can make Claude Code worse than no CLAUDE.md at all. When your configuration fights against you instead of helping, every interaction becomes frustrating.
This guide covers the 12 most common anti-patterns we’ve seen, why they happen, and how to fix them. We’ll also cover troubleshooting techniques for when things go wrong.
Part 1: The 12 Anti-Patterns
Anti-Pattern 1: The Novel
Symptom: Your CLAUDE.md is 500+ lines with every rule you’ve ever thought of.
What it looks like:
# CLAUDE.md (847 lines)
## Code Style (217 lines)
- Use camelCase for variables
- Use PascalCase for classes
- Use SCREAMING_SNAKE_CASE for constants
- Use kebab-case for file names
- Indent with 2 spaces, not tabs
- Maximum line length 100 characters
- Always use semicolons
- Prefer const over let
- Never use var
... (200 more lines)
Why it’s a problem: Claude has to process all this context every session. Most of it is generic advice that Claude already knows. You’re wasting tokens and potentially causing Claude to miss the important stuff.
Fix:
# Code Standards
Follow standard TypeScript conventions. Specific overrides:
- 4-space indentation (not 2)
- No semicolons (Prettier handles this)
- Maximum 80 characters per line
See @.eslintrc.js and @.prettierrc for details.
Rule of thumb: If it’s covered by your linter/formatter config, don’t repeat it in CLAUDE.md.
Anti-Pattern 2: The Paranoid Parent
Symptom: Every action requires confirmation. Claude asks permission constantly.
What it looks like:
# Permissions
- Ask before reading any file
- Ask before writing any file
- Ask before running any command
- Ask before making any change
- Never assume - always ask
Why it’s a problem: This destroys productivity. You spend more time approving actions than getting work done.
Fix:
# Autonomous Operations (No confirmation needed)
- Read any file in the project
- Create/modify files in src/, tests/, docs/
- Run: npm test, npm run lint, npm run build
- Create local git branches
- Install devDependencies
# Requires Confirmation
- Install production dependencies
- Modify .env or config files
- Push to remote
- Delete files
- Run database migrations
Use settings.json for fine-grained control:
{
"permissions": {
"allow": ["Read", "Write(src/**)", "Bash(npm run:*)"],
"deny": ["Write(.env*)", "Bash(rm -rf:*)"]
}
}
Anti-Pattern 3: The Ghost Town
Symptom: CLAUDE.md exists but says almost nothing useful.
What it looks like:
# CLAUDE.md
This is a React project.
Why it’s a problem: Claude has to guess everything - your conventions, your tech stack, your preferences. Each session starts from zero.
Fix: Include at minimum:
# Project Overview
E-commerce platform with Next.js 14 App Router, PostgreSQL, and Stripe.
# Tech Stack
- Next.js 14 (App Router)
- TypeScript (strict mode)
- Prisma + PostgreSQL
- Tailwind CSS
- Vitest for testing
# Commands
- npm run dev # Start development (port 3000)
- npm test # Run tests
- npm run lint # Check code quality
# Directory Structure
src/
├── app/ # Next.js routes and pages
├── components/ # Shared React components
├── lib/ # Utility functions
└── services/ # Business logic
Anti-Pattern 4: The Copy-Paste Special
Symptom: You copied someone else’s CLAUDE.md without understanding or adapting it.
What it looks like:
# From some tutorial
- Use Rust's ownership model
- Follow Elm architecture
- Test with pytest
# Your actual project: React + TypeScript
Why it’s a problem: Conflicting or irrelevant instructions confuse Claude. It may apply rules that don’t fit your project.
Fix: Start fresh. Answer these questions:
- What does this project do?
- What’s the tech stack?
- What are the essential commands?
- What are MY specific conventions?
- What actions need protection?
Build your CLAUDE.md from your answers, not someone else’s template.
Anti-Pattern 5: The Time Capsule
Symptom: CLAUDE.md hasn’t been updated in months. It references deprecated patterns or old tech.
What it looks like:
# Last updated: 2024-03-15
## Database
Use MongoDB with Mongoose models.
# (You migrated to PostgreSQL 6 months ago)
Why it’s a problem: Claude follows outdated instructions, creating code that doesn’t fit your current architecture.
Fix: Schedule reviews:
# CLAUDE.md
Last updated: 2026-01-14
Version: 3.2
## Review Triggers
- [ ] After major feature completion
- [ ] When tech stack changes
- [ ] When team joins/leaves
- [ ] Monthly review (1st of month)
## Recent Changes
- 3.2: Migrated from MongoDB to PostgreSQL
- 3.1: Added API validation requirements
- 3.0: Restructured for Claude Code v2.0
Anti-Pattern 6: The Contradiction Machine
Symptom: Different parts of CLAUDE.md give conflicting instructions.
What it looks like:
# Testing
All features must have unit tests.
Aim for 90% coverage.
...
# Quick Iterations
Skip tests for rapid prototyping.
Don't let tests slow you down.
Why it’s a problem: Claude doesn’t know which instruction to follow. Behavior becomes unpredictable.
Fix: Use explicit priority and exceptions:
# Testing (NON-NEGOTIABLE)
All features must have unit tests.
Minimum 80% coverage for new code.
**Exceptions:**
- Files prefixed with `_experimental`
- Scripts in `scripts/` directory
- When explicitly told to skip tests
Anti-Pattern 7: The Jargon Jungle
Symptom: CLAUDE.md uses internal jargon or acronyms that Claude doesn’t know.
What it looks like:
# Rules
- All PFRs must pass QG3
- Follow the BATS pattern for services
- Use DTOs for the gateway layer
- Ensure FE/BE parity on the ACME endpoints
Why it’s a problem: Claude interprets unknown terms unpredictably or ignores them entirely.
Fix: Define your terms:
# Glossary
- PFR: Pull Feature Request (our term for feature branches)
- QG3: Quality Gate 3 (tests pass, coverage >80%, no lint errors)
- BATS: Business-API-Transform-Store (our service layer pattern)
- DTO: Data Transfer Object (typed interfaces for API boundaries)
# Rules
- All feature branches (PFRs) must pass QG3 before merge
- Services follow BATS pattern: see @docs/bats-pattern.md
Anti-Pattern 8: The Security Theater
Symptom: Security rules that sound impressive but don’t actually protect anything meaningful.
What it looks like:
# Security
- Never use eval()
- Don't use innerHTML
- Sanitize all inputs
- Use parameterized queries
Why it’s a problem: These are generic rules Claude already follows. Real security risks in your specific codebase go unaddressed.
Fix: Focus on YOUR actual risks:
# Security (Project-Specific)
## Payment Processing (src/services/payment/)
- All Stripe API calls must use the wrapper in lib/stripe.ts
- Never log full card numbers (only last 4 digits)
- PCI compliance: no card data in error messages
## Authentication (src/services/auth/)
- JWT secrets must come from environment variables only
- Token expiry: 15 minutes (access), 7 days (refresh)
- Rate limit: 5 failed attempts = 15 minute lockout
## Data Handling
- PII fields (email, name, address) must be encrypted at rest
- Use the sanitize() helper from lib/security.ts for user inputs
Anti-Pattern 9: The Micromanager
Symptom: Instructions so specific that Claude can’t adapt to edge cases.
What it looks like:
# Error Handling
1. First check if error is network error
2. If network error, show "Network error occurred"
3. If not network error, check if error is validation error
4. If validation error, show field-specific message
5. If not validation error, check if error is auth error
6. If auth error, redirect to /login
7. Otherwise show "An error occurred"
Why it’s a problem: Real errors are messier. This rigid flowchart breaks on the first unexpected case.
Fix: Give principles, not procedures:
# Error Handling Principles
- User-facing errors: Friendly messages without technical details
- Developer errors: Full stack traces in development mode
- Network errors: Suggest retry, offer offline mode if available
- Auth errors: Redirect to login, preserve return URL
- Use the ErrorBoundary component for React error handling
- Log all errors to monitoring (see lib/monitoring.ts)
## Error Response Format
{ error: string, code: string, details?: object }
See @src/types/errors.ts for full type definitions.
Anti-Pattern 10: The Wishful Thinker
Symptom: CLAUDE.md describes how you wish things worked, not how they actually work.
What it looks like:
# Architecture
We follow clean architecture with clear separation:
- Domain layer: Pure business logic
- Application layer: Use cases
- Infrastructure layer: External services
- Presentation layer: UI components
# (Reality: Everything is in components/ with no separation)
Why it’s a problem: Claude writes code for your ideal architecture, not your real codebase. The new code doesn’t fit.
Fix: Be honest about current state:
# Architecture (Current State)
Most logic is in React components. We're gradually extracting:
- Business logic → src/services/ (in progress)
- API calls → src/lib/api.ts (done)
- Shared types → src/types/ (done)
# Architecture (Target State)
See @docs/target-architecture.md for the end goal.
# Migration Rules
- New features: Use services layer
- Bug fixes: OK to modify existing component logic
- Refactoring: Extract to services when touching files
Anti-Pattern 11: The One Size Fits All
Symptom: Same rules apply to everything, regardless of context.
What it looks like:
# Standards
- 100% test coverage
- Full JSDoc documentation
- Comprehensive error handling
- Performance optimization
Why it’s a problem: Not everything needs the same rigor. Prototype code and production code have different needs.
Fix: Use context-aware rules:
# Standards by Context
## Production Code (src/services/, src/lib/)
- 90% test coverage minimum
- JSDoc for all public APIs
- Full error handling with typed errors
- Performance profiling for hot paths
## UI Components (src/components/)
- 70% test coverage
- Props documentation required
- Error boundaries at page level
## Scripts & Tools (scripts/, tools/)
- Tests optional
- Minimal documentation
- Happy path focus
## Experiments (src/_experimental/)
- No coverage requirements
- Will be deleted or promoted within 2 weeks
Anti-Pattern 12: The Silo
Symptom: Team members each have different CLAUDE.md files with conflicting standards.
What it looks like:
# Alice's CLAUDE.md: "Use Redux for state"
# Bob's CLAUDE.md: "Use Zustand for state"
# Carol's CLAUDE.md: "Use React Query for state"
Why it’s a problem: Code becomes inconsistent. PRs have style conflicts. Onboarding is confusing.
Fix: Use the layer hierarchy properly:
.claude/CLAUDE.md # Shared team standards (committed)
CLAUDE.local.md # Personal preferences (gitignored)
~/.claude/CLAUDE.md # Global personal settings
Team agreement:
# .claude/CLAUDE.md (Team Version)
## State Management
- Server state: React Query
- Client state: Zustand
- Form state: React Hook Form
## Individual Preferences
Use CLAUDE.local.md for personal overrides.
Do NOT modify shared CLAUDE.md without team discussion.
Part 2: Troubleshooting Guide
Problem: Claude Ignores My CLAUDE.md
Check 1: File location
# Correct locations:
./CLAUDE.md # Project root
./.claude/CLAUDE.md # Hidden directory
Check 2: File is being read Ask Claude: “What instructions from CLAUDE.md are you following?”
Check 3: Priority conflicts
Priority: CLAUDE.local.md > ./CLAUDE.md > ~/.claude/CLAUDE.md
A local override might be hiding your project rules.
Problem: Claude Keeps Asking for Permission
Check 1: Permission settings
// .claude/settings.json
{
"permissions": {
"allow": ["Read", "Write", "Edit", "Bash(npm:*)"]
}
}
Check 2: Conflicting CLAUDE.md instructions Look for phrases like “always ask” or “confirm before” and remove them.
Check 3: Enterprise restrictions
If you’re in an organization, check /etc/claude-code/settings.json for enterprise policies.
Problem: Claude Uses Wrong Conventions
Check 1: Conventions are explicit
# Don't:
Use standard React patterns.
# Do:
## React Patterns
- Functional components only
- Named exports (not default)
- Props interface named [ComponentName]Props
- Hooks in separate files when shared
Check 2: Examples are provided
## Component Template
See @src/components/_template.tsx for our standard structure.
Problem: Claude Doesn’t Remember Previous Sessions
Check 1: Memory MCP is configured
claude mcp add --scope project memory \
-e MEMORY_FILE_PATH=./.claude/memory.json \
-- npx -y @modelcontextprotocol/server-memory
Check 2: Memory file exists and is readable
cat .claude/memory.json
Check 3: You’re using memory commands
/memory-saveto store important context/memory-searchto recall previous decisions
Problem: settings.json Not Working
Check 1: JSON is valid
cat .claude/settings.json | jq .
Check 2: Correct property names
{
"permissions": {
"allow": [...], // lowercase
"deny": [...] // lowercase
},
"enableAllProjectMcpServers": true,
"ignorePatterns": [...]
}
Check 3: MCP server permissions
claude mcp list
claude mcp reset-project-choices
Problem: Rules Directory Not Loading
Check 1: Correct structure
.claude/
├── CLAUDE.md
└── rules/
├── code-style.md
└── testing.md
Check 2: Claude Code version Path-specific rules require v2.0.20+:
claude --version
Check 3: Frontmatter syntax
---
paths: src/api/**/*.ts
---
Rules for API files...
Quick Reference: CLAUDE.md Health Check
Run through this checklist monthly:
## CLAUDE.md Health Check
### Length
- [ ] Under 200 lines
- [ ] No redundant information
- [ ] Details extracted to rules/
### Clarity
- [ ] No jargon without definitions
- [ ] Specific, actionable rules
- [ ] Examples where helpful
### Accuracy
- [ ] Matches current tech stack
- [ ] Reflects actual architecture
- [ ] No contradictions
### Permissions
- [ ] Autonomous operations defined
- [ ] Only truly risky actions need confirmation
- [ ] settings.json configured properly
### Maintenance
- [ ] Last updated date present
- [ ] Changelog maintained
- [ ] Review schedule set
Summary
The best CLAUDE.md files share these qualities:
- Concise: Under 200 lines, focused on what’s unique
- Honest: Describes reality, not aspirations
- Specific: Actionable rules, not vague principles
- Layered: Uses the hierarchy (global, project, local)
- Maintained: Regularly updated as the project evolves
When troubleshooting, always check:
- Is the file in the right location?
- Is there a priority conflict?
- Are the instructions explicit enough?
- Is there a version mismatch?
A great CLAUDE.md doesn’t try to control everything - it provides just enough guidance for Claude to make good decisions.
Sources: Claude Code Documentation, Claude Code GitHub