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.
/contextlists 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
@pathimports 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:
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
 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.mdbelow 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.mdis appended afterCLAUDE.mdat 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-dirdoes not bring memory files. SetCLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1if 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.mdfrom another team is loaded silently. UseclaudeMdExcludesto 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:
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
PreToolUsehook 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.denyremoves 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:anchorsreproducesrehype-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-promptraises 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.
/contextanswers 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?
How do I tell whether my CLAUDE.md actually loaded?
How long should CLAUDE.md be?
Does splitting CLAUDE.md into imports reduce context usage?
What should I use instead of CLAUDE.md for a rule that must never be broken?
Muhammad Kashif
Founder and editor of Devventa, covering AI coding assistants, Next.js and the modern AI development stack.




