lockstep
9 min readNaman Jain

Why Claude Code ignores your CLAUDE.md (and how to fix it)

Claude Code ignoring CLAUDE.md? The seven real causes, from files that never loaded to rules lost after compaction, how to check each, and when to use a hook.

Your CLAUDE.md says "Never commit directly to main." Claude Code commits directly to main.

You add the rule again in capital letters. You add "IMPORTANT" in front of it. Two days later it happens again, and now you wonder whether Claude reads the file at all.

It usually does. The problem is what Claude Code does with that file, and it has specific, checkable causes. This guide walks through each one, using Anthropic's own memory documentation and compaction table, checked on 4 November 2026.

Why Claude Code ignores CLAUDE.md

Claude Code ignores CLAUDE.md instructions because the file is context, not configuration. It arrives as a user message after the system prompt, and Anthropic's documentation says there is no guarantee of strict compliance, especially for vague or conflicting instructions.

Within that limit, an ignored instruction almost always has one of seven causes:

  1. The file never loaded.
  2. The instruction was summarized away during compaction.
  3. The file is too long.
  4. Two instructions disagree.
  5. The instruction is too vague to act on.
  6. Claude Code's own built-in guidance competes with it.
  7. A subdirectory file was cut off at its size limit.

Each cause has a different check. Start at the top, because the first one is the fastest to rule out.

You are not the only one

Ignored CLAUDE.md instructions are one of the most reported problems in the Claude Code issue tracker. A few examples:

IssueStatusComments
#2544: CLAUDE.md mandatory rules consistently ignored across multiple repositoriesOpen34
#2901: Claude Code frequently violates explicit project and user instructions defined in CLAUDE.mdClosed31
#53223: CLAUDE.md/AGENTS.md instruction compliance is architecturally unenforcedOpen31
#19471: CLAUDE.md instructions completely ignored after context compactionClosed28
#6354: Claude forgets everything in CLAUDE.md after compactionOpen24

Comment counts as of 4 November 2026. Two of the five are about compaction, which is cause 2 below.

Cause 1: the file never loaded

Claude can't follow a file it never received. Run /context and look under Memory files. If your CLAUDE.md isn't listed, nothing you write in it matters yet.

Common reasons a file doesn't load:

  • It's in a subdirectory. CLAUDE.md files below your working directory load on demand, only after Claude reads, writes, or edits a file in that folder. They won't appear in /context at the start.
  • You started Claude in the wrong place. Claude loads CLAUDE.md from the directory you launched in and every directory above it. A file in a sibling folder is invisible.
  • An AGENTS.md question. If both exist, Claude reads CLAUDE.md by default and skips AGENTS.md. A CLAUDE.local.md counts too, so adding one can stop your AGENTS.md from loading.
  • A claudeMdExcludes pattern skips it. Common in monorepos.
  • It's over 4 MiB. Claude Code skips the whole file.
  • It came from --add-dir. Extra directories don't load their CLAUDE.md unless CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 is set.

Cause 2: the instruction was lost after compaction

When a long session compacts, Claude Code summarizes the conversation to free space. Some memory comes back from disk. Some doesn't.

What you wroteAfter compaction
Project-root CLAUDE.mdRe-injected from disk
Rules in .claude/rules/ without pathsRe-injected from disk
Auto memoryRe-injected from disk
Rules with paths: frontmatterSummarized away. Reloaded only when Claude touches a matching file
CLAUDE.md in a subdirectorySummarized away. Reloaded only when Claude touches a file there
An instruction you typed in chatSummarized with everything else. It may not survive

The fix depends on the row. If a rule must hold for the whole session, move it to the project-root CLAUDE.md or remove its paths field. If you gave the instruction in chat, it was never memory: write it into CLAUDE.md.

For context that must come back after every compaction, Claude Code supports a SessionStart hook with a compact matcher. Whatever the command prints is added to Claude's context after compaction:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "compact",
        "hooks": [
          { "type": "command", "command": "cat .claude/after-compact.md" }
        ]
      }
    ]
  }
}

Keep that file short. It is a reminder, not a second CLAUDE.md.

Cause 3: the file is too long

A long CLAUDE.md is followed less reliably than a short one. Anthropic recommends under 200 lines per file, and Claude Code shows a warning at startup and in /status when a file is over that length, or when several files add up past a combined limit.

Splitting the file with @imports does not fix this. Imported files load together with the file that imports them, so the context cost is the same. What does help:

  • Move rules that only apply to some files into .claude/rules/ with paths, so they load only when relevant.
  • Move multi-step procedures into a skill, which loads when it is needed.
  • Delete what Claude can work out from the code. Directory layouts and dependency lists don't need to be in the file.

Cause 4: two instructions disagree

Claude Code concatenates every CLAUDE.md and rules file it loads. Nothing overrides anything. If two instructions conflict, the documentation says Claude may pick one arbitrarily.

Conflicts hide in places you don't look together: your personal ~/.claude/CLAUDE.md, the project file, a nested file in a package, a rule written months ago. "Use npm" in one and "use pnpm" in another produces exactly the inconsistent behavior that feels like being ignored.

Run /doctor prompt-audit (Claude Code v2.1.283 or later). It looks for contradictions, outdated instructions, and references to files or commands that no longer exist, and changes nothing until you approve the edits.

Cause 5: the instruction is too vague

Claude follows instructions it can check. Compare:

VagueSpecific
Write good testsRun npm test before committing. Add a test for every new API handler
Keep files organizedAPI handlers live in src/api/handlers/
Be careful with the databaseNever edit files in db/migrations/. Create a new migration instead
Format code properlyUse 2-space indentation

Capital letters and "IMPORTANT" are not a substitute for precision. If you can't tell from a diff whether the rule was followed, Claude can't either.

Cause 6: Claude Code's built-in guidance competes

Claude Code adds its own instructions about git commits and pull requests. If your CLAUDE.md sets different commit or PR rules, the two compete.

The documentation's fix is to turn off the built-in git guidance with the includeGitInstructions setting, and to set attribution text with the attribution setting, so your rules are the only ones in play.

Cause 7: a subdirectory file was cut off

CLAUDE.md files in subdirectories and path-scoped rules have a per-file size limit. Past it, Claude receives only the start of the file, with a note to read the rest. Until it does, the later instructions aren't in context.

The limit is 40,000 characters on a 200K context window, and 150,000 to 200,000 characters on a 1M window depending on the model. Check a file with wc -m path/to/CLAUDE.md. If it is over, split it into several rules files, which each count separately.

When a rule must never be broken, use a hook

Some instructions are not preferences. "Never edit applied migrations" or "never touch .env" should not depend on a model's judgment. For those, Claude Code has two enforcement tools that run outside the model:

  • A permissions.deny rule in settings blocks specific tools, commands, or file paths.
  • A PreToolUse hook runs a script before a tool call. If the script exits with code 2, the call is blocked and Claude sees your reason.

A small hook that blocks edits to applied migrations:

#!/bin/bash
# .claude/hooks/protect-migrations.sh
FILE_PATH=$(jq -r '.tool_input.file_path // empty')

if [[ "$FILE_PATH" == *"db/migrations/"* ]]; then
  echo "Blocked: applied migrations are read-only. Create a new migration." >&2
  exit 2
fi
exit 0

Make it executable with chmod +x, then register it in .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-migrations.sh"
          }
        ]
      }
    ]
  }
}

The script uses jq to read the tool input. Anthropic's hooks guide has a fuller version for protecting several paths.

Keep the line in CLAUDE.md too. The hook stops the action; the instruction tells Claude why, so it plans around the rule instead of running into it.

A two-minute checklist

When Claude Code ignores an instruction, go down this list:

  1. Run /context. Is the file under Memory files?
  2. Did the session compact? Is the rule path-scoped, nested, or only in chat?
  3. Is the file over 200 lines?
  4. Does another file say something different? Run /doctor prompt-audit.
  5. Could you check the rule from a diff? If not, rewrite it.
  6. Is it about commits or PRs? Check includeGitInstructions.
  7. Must it never be broken? Make it a hook or a deny rule.

For the full picture of what loads, when, and how much, see how Claude Code memory works.

What CLAUDE.md can't hold

Some ignored instructions aren't load or wording problems. They are decisions that changed after someone wrote them down.

A CLAUDE.md line says "exports never include the email field." Last week the product lead approved an exception for internal admins in a Slack thread. The file still says never, a teammate's agent follows the file, and the new feature ships without the exception. Nothing was ignored. The file was simply out of date, and nobody owned updating it.

CLAUDE.md has no owner per line, no status, and no record of what replaced what. It works for stable instructions about how a repository works. It does not work well for product and architecture decisions that change, involve people outside the repo, and need to reach every teammate's agent at once.

Where Lockstep fits

Lockstep keeps that second kind of instruction. Decisions are captured from PRDs, Slack, and pull requests, and become binding when their owner approves them. Claude Code is briefed on the decisions that apply at the start of each session, and when a decision is replaced, the old version is marked as replaced rather than left in a file to contradict the new one.

It does not make Claude Code obey anything, and it does not replace CLAUDE.md or hooks. Keep repository instructions in CLAUDE.md and hard limits in hooks. Use Lockstep for the decisions your team makes outside the repo. Session briefings ship for Claude Code today. Try it on one repository with npx lockstep-cli onboard.

Sources checked 4 November 2026

For every memory file and limit in one place, read how Claude Code memory works. For what to save between sessions, see Claude Code keeps forgetting context?. For what belongs in the file at all, see CLAUDE.md vs agent memory.

Frequently asked questions

Why does Claude Code ignore my CLAUDE.md?
Claude Code delivers CLAUDE.md as a message after the system prompt and treats it as context, not enforced configuration. Common causes are a file that never loaded, an instruction lost after compaction, a file past 200 lines, conflicting instructions across files, vague wording, and competing built-in guidance.
How do I check whether Claude Code loaded my CLAUDE.md?
Run /context in the session and look under Memory files. A CLAUDE.md in a subdirectory will not be listed there, because it loads only when Claude reads, writes, or edits a file in that subdirectory. Run /memory to open the files that did load.
Why does Claude Code forget CLAUDE.md after compaction?
The project-root CLAUDE.md and unscoped rules are re-injected from disk after compaction. Path-scoped rules and nested CLAUDE.md files are summarized away with the conversation and only come back when Claude touches a matching file again. Instructions typed only in chat can be lost.
How do I make Claude Code always follow a rule?
You can't guarantee it with CLAUDE.md. For an action that must never happen, use a PreToolUse hook that exits with code 2 to block it, or a permissions.deny rule in settings. Both are enforced by Claude Code itself, regardless of what the model decides.
Is a longer CLAUDE.md better?
No. Anthropic's documentation recommends under 200 lines per file and says longer files use more context and reduce adherence. Splitting a file with @imports does not help, because imported files load with the file that imports them. Use path-scoped rules instead.

Keep reading