Skip to main content

Pitfalls

Most CLAUDE.md failures are silent. Claude does not warn you when it ignores an instruction, follows the wrong version of a conflicting rule, or runs out of attention budget. The failure mode is subtle degradation — Claude does slightly worse over time, and you blame the model instead of your instructions.

Instruction Conflicts Between Layers

When ~/.claude/CLAUDE.md says "use tabs" and ./CLAUDE.md says "use spaces," Claude picks one arbitrarily. There is no deterministic resolution between scopes. The project file loaded later might win due to recency bias, but this is probabilistic, not guaranteed.

Common Conflict Sources

ConflictCause
Package manager mismatchUser-level says npm, project says pnpm
Test runner disagreementRoot CLAUDE.md says jest, subdirectory says vitest
Style contradictionsGlobal says "verbose error messages", project says "terse responses"
Monorepo cross-contaminationAncestor CLAUDE.md from another team's directory

Detection and Prevention

Run /memory to see every CLAUDE.md file currently loaded. Audit for contradictions manually — there is no automated conflict detection.

For monorepos, use claudeMdExcludes in .claude/settings.local.json to skip irrelevant ancestor files:

{
  "claudeMdExcludes": [
    "**/other-team/CLAUDE.md",
    "**/packages/legacy-service/.claude/rules/**"
  ]
}

The discipline is simple: each instruction should exist in exactly one file. If you find the same topic addressed in multiple CLAUDE.md files, consolidate.

Context Window Pressure

The most common and most damaging pitfall. Every token in CLAUDE.md is a token unavailable for conversation, tool output, and reasoning.

Quantified Impact

ScenarioToken Cost% of 200K Context
Lean CLAUDE.md (50 lines) + startup~8,5004.3%
Moderate CLAUDE.md (150 lines) + startup~10,5005.3%
Bloated CLAUDE.md (400 lines) + startup~14,0007.0%
Bloated CLAUDE.md + 3 @imports~22,00011.0%
Above + lazy-loaded monorepo files (5 packages)~30,00015.0%

LLM output quality starts degrading at 20-40% context fill. A bloated instruction setup combined with a moderately long conversation can push past this threshold well before any hard limit.

The @import Trap

# BAD: imports entire files into every session
@docs/architecture.md
@docs/api-reference.md
@docs/deployment-guide.md
@CONTRIBUTING.md

Each import embeds the full file into context at startup. A 500-line architecture doc costs ~5,000 tokens on every session, even when you are fixing a one-line typo. Multiply by four imports and you have 20,000 tokens of instructions before typing a word.

Fix: Only import files that are short and universally needed. For reference documentation, tell Claude to read on demand:

# Architecture docs are in docs/architecture.md -- read when working on structural changes.

Lazy Loading Accumulation

In long sessions exploring a monorepo, context fills with lazily-loaded CLAUDE.md files from every subdirectory Claude visits. Five package directories with 100-line CLAUDE.md files each add ~5,000 tokens mid-session, with no warning.

Fix: Use /clear between unrelated tasks. Use claudeMdExcludes to skip packages you are not working on. Keep subdirectory CLAUDE.md files short — under 50 lines each.

Stale Instructions

Instructions that were correct six months ago but now cause wrong behavior:

# Outdated -- causes errors
- Run `yarn test` for unit tests     # Team switched to pnpm three months ago
- Database models are in src/models/  # Moved to src/db/entities/ in last refactor
- Use Express 4 middleware patterns   # Upgraded to Express 5 last sprint

Claude follows stale instructions faithfully. It has no way to detect that yarn test will fail because the lockfile is pnpm-lock.yaml. The model trusts your CLAUDE.md over filesystem evidence.

Prevention

Treat CLAUDE.md like code. Review it during refactors, dependency upgrades, and directory restructures. The /init command (with CLAUDE_CODE_NEW_INIT=1 for the enhanced flow) re-analyzes your codebase and suggests updates.

A quarterly audit takes 10 minutes and prevents hours of debugging wrong agent behavior.

A practical audit checklist embedded as HTML comments at the bottom of your CLAUDE.md:

<!-- AUDIT LOG
  Last reviewed: 2026-03-15
  Reviewed by: @dakota
  Next review: 2026-06-15
  Changes: removed yarn references, updated test command to vitest
-->

Use the enhanced /init flow to compare your CLAUDE.md against current project state:

CLAUDE_CODE_NEW_INIT=1 claude /init

This scans package.json, directory structure, and config files, then flags instructions that conflict with what it finds.

Instructions That Get Ignored

Five reasons Claude ignores a CLAUDE.md instruction:

  1. The file is too long and the rule is lost in noise. At 400+ lines, individual instructions compete for attention. Rules in the middle section get the least attention.
  2. The instruction is vague. "Format code nicely" gives Claude no actionable target. "Use 2-space indentation in TypeScript files" does.
  3. Instructions contradict each other across layers. Claude picks one; it might not be yours.
  4. The instruction uses negation. "Do NOT use semicolons" forces Claude to process the concept then negate it. Error-prone by design.
  5. The instruction states what Claude would do anyway. Wasted tokens, diluted attention, zero benefit.

Diagnostic Process

If Claude keeps violating a specific rule:

  1. Check file length — is your CLAUDE.md over 200 lines?
  2. Check instruction position — is the rule buried in the middle?
  3. Check for conflicts — does another CLAUDE.md file contradict it?
  4. Check phrasing — is it concrete and verifiable?
  5. Check necessity — does Claude need this instruction at all?

If Claude asks questions that are answered in CLAUDE.md, the phrasing is likely ambiguous. Rewrite the instruction to be unambiguous.

Before (ambiguous):

- Use the right testing approach for each module
- Keep components small
- Follow our API patterns

After (concrete and verifiable):

- Unit test files with vitest: `pnpm test -- path/to/file.test.ts`
- Components under 150 lines; split into subcomponents at that threshold
- API handlers return `{ data, error, meta }` envelope (see src/types/api.ts)

Anti-Patterns

The Kitchen Sink

# BAD: 400+ lines covering everything
 
## Project Overview
[30 lines about the company and product history]
 
## Architecture
[50 lines describing every service and database]
 
## API Documentation
[100 lines of endpoint descriptions]
 
## Code Style
[40 lines of style rules, most matching language defaults]
 
## Testing
[30 lines, half of which are obvious]
 
## Deployment
[20 lines about CI/CD pipeline details]
 
## Team Practices
[30 lines about code review process]

Fix: Keep only what Claude needs every session. Move API docs to a skill. Move architecture to a skill triggered by relevant file access. Move deployment to a /deploy skill. Delete anything Claude can infer from reading code. Target: under 200 lines total.

Linting by CLAUDE.md

# BAD: using an LLM to do a linter's job
- Always add semicolons at end of statements
- Use single quotes for strings
- Maximum line length: 100 characters
- Sort imports alphabetically
- Add trailing commas in multi-line arrays

LLMs are expensive, slow, and probabilistic. Linters are free, fast, and deterministic. These 5 lines consume attention budget while achieving worse compliance than a .prettierrc file.

Fix: Configure ESLint and Prettier. Add a PostToolUse hook to auto-format:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write 2>/dev/null; true"
          }
        ]
      }
    ]
  }
}

Wrong-Layer Instructions

# BAD: personal preferences in project CLAUDE.md (committed to git)
- I prefer verbose error messages
- When I say "fix it", run the full test suite first
- Use dark theme colors in UI components

Your teammates do not share your preferences. Personal instructions go in ~/.claude/CLAUDE.md or CLAUDE.local.md.

# BAD: project-specific build commands in user-level CLAUDE.md
- Run `pnpm test` for unit tests
- Database migrations: `pnpm db:migrate`

These break when you switch projects. Project-specific commands go in the project CLAUDE.md.

The Documentation Mirror

# BAD: duplicating what's already in README or docs
## Getting Started
1. Clone the repository
2. Install dependencies with pnpm install
3. Copy .env.example to .env
4. Run pnpm dev to start the dev server

Claude can read your README. Instead:

# Setup instructions are in README.md

One line replaces fifteen, and the README is always the source of truth.

Performance Implications

Understanding how token cost accumulates across a session:

  • Each CLAUDE.md file loads fully into context (no truncation, unlike auto memory's 200-line limit)
  • @imports expand recursively (up to 5 levels) and embed completely
  • Path-scoped rules load when matching files are touched, accumulating over a session
  • Subdirectory CLAUDE.md files accumulate as Claude explores more directories
  • After compaction, project-root CLAUDE.md re-injects (consuming tokens again), but subdirectory files only reload when re-touched

The Session Lifecycle Problem

A typical long session in a monorepo:

  1. Start: ~8,000 tokens of startup overhead
  2. Touch packages/api/: lazy-loads API CLAUDE.md (+500 tokens)
  3. Touch packages/frontend/: lazy-loads frontend CLAUDE.md (+500 tokens)
  4. Touch packages/shared/: lazy-loads shared CLAUDE.md (+500 tokens)
  5. Path-scoped rules trigger for test files, API routes, components (+1,500 tokens)
  6. Compaction fires: project-root re-injects, subdirectory files lost
  7. Re-touch packages: lazy-loads them again (+1,500 tokens cumulative)

By step 7, instruction-related tokens have consumed 12,000+ tokens across the session, some of it redundant re-loading after compaction.

Fix: Use /clear between unrelated tasks. Keep subdirectory files lean. Prefer path-scoped rules over subdirectory CLAUDE.md files when possible — they are more targeted and load less content.

The Maintenance Burden

CLAUDE.md is code. It requires the same discipline as any other configuration file:

  • Review during refactors. Renaming directories? Update file paths in CLAUDE.md.
  • Review during dependency changes. Switching test runners? Update the test command.
  • Prune quarterly. Delete instructions that no longer apply or that Claude follows without being told.
  • Measure compliance. If Claude consistently follows a rule without the instruction, remove it. If Claude consistently ignores a rule despite the instruction, investigate why.

Track which instruction files are loaded during a session by adding an InstructionsLoaded hook:

{
  "hooks": {
    "InstructionsLoaded": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date -Iseconds) $CLAUDE_INSTRUCTIONS_FILE ($CLAUDE_INSTRUCTIONS_REASON)\" >> .claude/instruction-audit.log"
          }
        ]
      }
    ]
  }
}

Review the log after a typical work session. Files that load frequently but contain rarely-needed instructions are candidates for conversion to skills or removal.

The instructions that degrade agent performance the most are the ones nobody remembers writing.