Skip to content

AI CODING ASSISTANTS

Claude Ignores CLAUDE.md: Why It Happens and How to Fix It

Claude ignores CLAUDE.md because Anthropic ships it as context, not configuration. Here is the measurement, the diagnosis order, and the fix that works.

If Claude ignores CLAUDE.md, the file is almost never the problem and rewriting it is almost never the fix. Anthropic's own memory documentation says CLAUDE.md is delivered as a user message after the system prompt and is treated as context, "not enforced configuration." This guide covers the mechanism, a measurement of how much difference writing a rule down actually makes, the order to diagnose a skipped instruction in, and the layer to move a rule to when it genuinely cannot be broken. It assumes you already have a file; the complete Claude Code guide covers where CLAUDE.md sits among the other extension points. Checked against Claude Code v2.1.224 in August 2026.

Key takeaways

  • CLAUDE.md is context, not configuration. Anthropic documents no guarantee of strict compliance, and says to use a hook when an action must be blocked regardless.
  • Across this site's 27 articles, rules backed by the build had 0 violations. Rules that existed only as prose had 89, in 13 files.
  • Check that the file loaded before rewriting it. /context lists the memory files a session actually read; an unlisted file is invisible, not ignored.
  • CLAUDE.md is loaded in full regardless of length — unlike auto memory's MEMORY.md, which is truncated at 200 lines or 25KB. Length degrades adherence; it does not remove content.
  • Splitting into @path imports does not reduce context. Only path-scoped .claude/rules/ files load conditionally.

Why Claude ignores CLAUDE.md

The mechanism is documented, and it is more specific than "the model is unreliable."

Anthropic's memory documentation states the delivery path directly: "CLAUDE.md content is delivered as a user message after the system prompt, not as part of the system prompt itself. Claude reads it and tries to follow it, but there's no guarantee of strict compliance, especially for vague or conflicting instructions."

The same page draws the distinction that matters: "Claude treats them as context, not enforced configuration. To block an action regardless of what Claude decides, use a PreToolUse hook instead."

So a CLAUDE.md rule competes for attention with everything else in the window — your prompt, the files just read, tool output. It is a strong prior, not a gate. That framing predicts which rules survive and which do not, and it is testable. For what belongs in the file in the first place, see setting up CLAUDE.md.

What 27 articles say about written rules

This site runs on two long standards documents. CLAUDE.md holds the project rules and content-rules.md holds the editorial ones. Both were written to be obeyed, and both have been in place for every article published here.

So we checked. scripts/check-content-rules.mjs audits every file in content/ against 14 rules taken verbatim from those documents, and tags each rule by how it is backed:

Terminal
npm run check:rules
# → 27 articles checked against 14 written rules.
# →
# → Enforced by the build — 3 rules, 0 violations
# →   clean
# → Enforced by an npm check — 2 rules, 0 violations
# →   clean
# → Written down only — 9 rules, 89 violations
# →   ordered-list: 89 in 13 file(s)

Three rules fail the build if broken: markdown ![]() images, {expression} MDX attributes, and undefined components. Zero violations. Two more are caught by an existing check. Zero violations.

The nine rules that exist only as sentences have 89 violations across 13 of 27 articles. Every one is the same rule — content-rules.md §4.9, which says ordered lists are unstyled and to use bolded labels in a bullet list instead. It is stated once in content-rules.md and again in this repository's CLAUDE.md. It was broken in nearly half the corpus.

The defect is real rather than cosmetic. app/globals.css styles .prose-article ul with list-style: disc and 22px of left padding, and styles li. There is no ol rule at all, so a numbered list renders with its numbers and its indent gone — the sequence the author wrote is invisible to the reader, while the text still looks fine.

The project's own roadmap had logged this defect against four articles. The measurement found 13.

Two bugs before the number meant anything

The first run of this script reported 143 violations, including a <hr> in all 27 articles and 13 stray # H1 headings. Both were wrong.

Every file in content/ is CRLF. Splitting on \n alone leaves a trailing \r on each line, so lines[0] === "---" was false, frontmatter was never detected, and every rule scanned the frontmatter as if it were body text. The 54 phantom horizontal rules were the frontmatter delimiters; the 13 phantom H1s were # comment lines inside one file's frontmatter.

The second bug was subtler. Two articles were flagged for markdown images because they discuss ![alt](src) in prose, inside backticks. The scanner now blanks inline code spans as well as fenced blocks — an article documenting a ban is not breaking it.

Both are worth stating because a checker that confidently reports 143 findings, all of them artifacts of its own line-ending handling, is the same failure mode as an instruction file you trust without verifying.

Check whether the file loaded at all

Before rewriting a single line, confirm Claude ever saw it. An unloaded file looks exactly like an ignored one.

Run /context in the session and read the list under Memory files. If your file is not named there, it did not load, and the fix is a path problem rather than a phrasing problem.

For a per-file trace, Anthropic documents an InstructionsLoaded hook that logs which instruction files are loaded, when, and why. That is the tool for path-scoped rules and for nested files in subdirectories, which load lazily and so are not present at startup.

The load rules that catch people out:

  • Subdirectory files load on demand, not at launch. A CLAUDE.md below your working directory arrives only when Claude reads a file in that directory.
  • Files above the working directory load in full at launch, walking up the tree.
  • Order is root-down. Instructions closer to where you launched Claude are read last, and CLAUDE.local.md is appended after CLAUDE.md at each level.
  • Block-level HTML comments are stripped before injection. A rule written inside <!-- ... --> never reaches the model, though it is still visible when you open the file.
  • --add-dir does not bring memory files. Set CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 if you want them.

Four causes, in the order worth checking

Ordered by how often each one is the answer, not by how easy it is to check.

  • The file never loaded. Covered above. Always rule this out first, because every other fix assumes the content is in context.
  • Two instructions conflict. Anthropic states that if two rules contradict each other, "Claude may pick one arbitrarily." This is the one that hides best in a monorepo, where an ancestor CLAUDE.md from another team is loaded silently. Use claudeMdExcludes to drop it, or reconcile the rules.
  • The instruction is not concrete enough to verify. "Use 2-space indentation" survives; "format code properly" does not. A rule you could not write a test for is a rule the model cannot reliably act on.
  • The instruction is stale. A rule that describes a file path or a command that has since moved is worse than no rule, because it competes with what the model can see in the codebase. CLAUDE.md mistakes that slow Claude Code down covers this failure mode in detail.

There is a fifth cause that is not the model's fault at all: the rule went into conversation rather than into the file. Project-root CLAUDE.md survives /compact, because Claude re-reads it from disk and re-injects it. Nested files and path-scoped rules are not re-injected, and anything you only said in chat is gone.

How long should CLAUDE.md be

Anthropic's documented target is under 200 lines per file, on the stated grounds that "longer files consume more context and reduce adherence."

One detail is widely misreported. The 200-line-or-25KB truncation applies to auto memory's MEMORY.md, not to CLAUDE.md. The docs are explicit: "This limit applies only to MEMORY.md. CLAUDE.md files are loaded in full regardless of length, though shorter files produce better adherence." A 400-line CLAUDE.md is not silently cut in half. It is fully present and less effective. For measured benchmarks on compliance decay curves across file sizes, see our guide to the CLAUDE.md character limit and 150k myth.

This repository's file is comfortably inside the target:

Terminal
npm run check:context-weight
# → SOURCE                    LINES    BYTES  ~TOKENS
# → project CLAUDE.md           135     6291     1573

Which is the point worth making: at 135 lines, length is not why any rule here was ignored — and 89 violations happened anyway. Length is a real effect and a poor first suspect. If your file is genuinely oversized, the CLAUDE.md cause of a slow Claude Code session measures what that costs per session.

Splitting does not help as much as people expect. Imports are "expanded and loaded into context at launch alongside the CLAUDE.md that references them," so @path buys organisation, not budget. The mechanism that does reduce cost is .claude/rules/ with a paths field, because a path-scoped rule enters context only when Claude reads a matching file.

Move the rule to a layer that enforces it

This is the fix. If a rule must hold, stop writing it in a file that documents itself as advisory.

Anthropic's own guidance splits the two cleanly: settings are "enforced by the client regardless of what Claude decides to do," while "CLAUDE.md instructions shape Claude's behavior but are not a hard enforcement layer."

  • A PreToolUse hook blocks the action. It runs as a shell command at a fixed lifecycle event, and exit code 2 rejects the tool call with a message the model sees.
  • permissions.deny removes the capability. Nothing negotiates with it.
  • A build-time error is the strongest option when the rule concerns files you commit. This site maps markdown images to a build failure with an explanatory message, and that rule has never once been broken.
  • A check in CI catches what the build cannot. npm run check:anchors reproduces rehype-slug's ID generation exactly; heading anchors have never drifted.

We re-ran this audit over 93 articles a month later, and the split held exactly: still zero violations on the gated rules, still one prose rule carrying all of them. The follow-up in Claude Code not following instructions also found the part this article could not see — compliance improved sharply after the failure was named, then relapsed after fifty-seven clean articles.

  • --append-system-prompt raises an instruction to system-prompt level for scripted runs. It must be passed on every invocation, so it suits automation rather than interactive work.

The pattern behind the measurement is simple: the three rules on this site that fail a build have zero violations across 27 articles, and the rule stated twice in prose has 89. Writing it down harder was available the whole time and would not have worked.

Common mistakes

  • Rewriting the file before checking it loaded. /context answers this in two seconds and invalidates most of the rewriting people do. An unlisted file is invisible, not disobedient.
  • Adding emphasis instead of enforcement. Capitals, "IMPORTANT", and repeating the rule three times all operate on the same advisory layer. Our most-violated rule already carried a ⛔.
  • Assuming a long file was truncated. CLAUDE.md loads in full at any length. That is MEMORY.md's limit, not this one.
  • Splitting into imports to save context. Imports load at launch. Path-scoped .claude/rules/ files are the mechanism that actually defers loading.
  • Writing the rule in an HTML comment. Block-level comments are stripped before the content reaches the model, so the rule is visible to you and to nobody else.
  • Trusting a checker you have not falsified. Ours reported 143 violations on its first run and every one was a line-ending bug.

Conclusion

Run /context first and confirm the file loaded; that alone resolves a large share of cases. Then look for a conflicting instruction, then for vagueness, then for staleness — in that order, because it is the order of frequency. Do not reach for length until you have ruled out the other four, and do not expect a rewrite to fix a rule that genuinely matters. Move that rule to a hook, a deny rule, or a build error, and let CLAUDE.md carry the conventions where advisory is good enough. For what belongs in the file once it is being read, see how to set up CLAUDE.md and our AGENTS.md vs CLAUDE.md comparison for multi-agent repositories.

Frequently asked questions

Why does Claude Code ignore my CLAUDE.md?
Because CLAUDE.md is context, not configuration. Anthropic's memory documentation states that Claude Code delivers the file as a user message after the system prompt and treats it as context rather than enforced configuration, so there is no guarantee of strict compliance. Vague instructions, instructions that conflict with another CLAUDE.md, and instructions that never loaded at all are the three most common reasons a specific rule gets skipped.
How do I tell whether my CLAUDE.md actually loaded?
Run /context in the session and read the list under Memory files. If your file is not named there, Claude cannot see it and no amount of rewriting will help. For a per-file trace of what loaded and when, add an InstructionsLoaded hook, which logs every instruction file the session reads including path-scoped rules and lazily loaded subdirectory files.
How long should CLAUDE.md be?
Anthropic's documented target is under 200 lines per file. Unlike auto memory's MEMORY.md, which is truncated at 200 lines or 25KB, CLAUDE.md is loaded in full regardless of length, so a long file is not silently cut. Length reduces adherence rather than removing content. Under 200 lines is a good target, but length is rarely the reason a specific rule is ignored.
Does splitting CLAUDE.md into imports reduce context usage?
No. Anthropic states that imported files are expanded and loaded into context at launch alongside the CLAUDE.md that references them, so @path imports help organisation but not context cost. Path-scoped rules in .claude/rules/ do reduce cost, because a rule with a paths field only enters context when Claude reads a matching file.
What should I use instead of CLAUDE.md for a rule that must never be broken?
A PreToolUse hook or a permissions.deny rule. Anthropic's documentation is explicit that to block an action regardless of what Claude decides, you use a hook instead of a memory file. Hooks run as shell commands at fixed lifecycle events, and settings rules are enforced by the client, so neither depends on the model choosing to comply.

Muhammad Kashif

Founder and editor of Devventa, covering AI coding assistants, Next.js and the modern AI development stack.