Key Takeaways
- Check that the file actually loaded before you blame the model. One command with a made-up word tells you.
- Any CLAUDE.md in your project, or in a folder above it, turns AGENTS.md off. Delete it or make it import AGENTS.md.
- In Claude Code a rule is scoped with
paths:.globs:is a Cursor key, and Claude Code ignores it. Our own kit had this wrong. - Only the “never” rules measurably change what the model does. Hand style preferences to a linter instead.
- If a rule must hold no matter what, put it in a deny rule, a hook, or a CI check. A markdown file can’t stop anything.
Claude Code loads your CLAUDE.md at the start of every session, and some sessions it still does the thing the file says never to do. On September 18 Anthropic made it read AGENTS.md as well, and five days later a Hacker News thread with 486 points showed the feature was silently off for anyone running with telemetry disabled (Hacker News, September 23, 2026). That bug is fixed, and it is one of ten reasons a rule can fail that we could reproduce on the current build, 2.1.289, with canary words in real files.
Each cause below comes with a test that takes under a minute and a fix. Causes one to five are about a file that never loaded, six to eight about a rule that loaded but lost out to the model, and nine and ten about rules that nothing enforces, or that nobody needs any more.
What Claude Code Loads, in Order
Half of the causes are about a file that never made it into the context, so the loading order comes first. Claude Code reads every source in this table, concatenates them in this order, and never lets one override another. When two disagree, the docs say Claude “may pick one arbitrarily” (Claude Code memory docs).
| Source | Loads | Note |
|---|---|---|
| Managed CLAUDE.md | Every session | Set by your organisation; does not count as a project file |
| ~/.claude/CLAUDE.md | Every session | Your personal notes; does not count either |
| CLAUDE.md chain | Every session, root first | CLAUDE.md, .claude/CLAUDE.md and CLAUDE.local.md in the folder and every parent |
| AGENTS.md | Only when no file from the row above exists | Since 2.1.277; changeable under Project instructions in /config |
| Rules with paths: | When a matching file is read or edited | .claude/rules/*.md; every other frontmatter key is ignored |
| Rules without paths: | Every session | Same priority as .claude/CLAUDE.md |
| Subfolder CLAUDE.md | When a file in that folder is touched | On demand, not at launch |
| MEMORY.md | Every session, first 200 lines | Claude’s own notes, stored outside the repo on your machine |
| SKILL.md | Description every session, body on use | Procedures you invoke, not standing rules |
What to put in each of these is a separate question, and our AGENTS.md guide answers it. This post is about why a rule that sits in the right file still gets broken.
The 30-Second Canary Test
Put a word that appears nowhere else in your repo into the file you suspect, then ask Claude for it from the command line. The command below uses CLAUDE.md; if the file in doubt is AGENTS.md or a rule, append the line there instead, and do not create a CLAUDE.md to test AGENTS.md, because that is cause 1. Delete the line when you are done.
printf 'The canary word is PERIWINKLE.\n' >> CLAUDE.md
claude -p 'Reply with only the canary word in your instructions, or NONE.' If the answer is NONE, the file almost certainly never loaded, and the cause is one of the first five; a smaller model occasionally answers NONE to a file that did load, so confirm with /memory in an interactive session, which lists every instruction file that loaded, including a directly loaded AGENTS.md on 2.1.280 and later. If the word comes back and Claude still breaks the rule, skip to cause six. Every version number in this post comes from Anthropic’s changelog, and every test was run on 2.1.289 on October 3.
Causes 1–5: It Never Loaded
Five ways the file never reaches the context. Each one is silent: no error, no warning, just a session that never saw the rule.
Cause 1: A stray CLAUDE.local.md is silencing your AGENTS.md
Since 2.1.277 Claude Code reads AGENTS.md, but only when no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md exists in the working folder or any folder above it. Any one of those, including a one-line scratch note you made months ago, switches AGENTS.md off. Our test folder with both files answered the canary from CLAUDE.local.md and never saw AGENTS.md.
d=$PWD; while [ "$d" != / ]; do
ls "$d"/CLAUDE.md "$d"/CLAUDE.local.md "$d"/.claude/CLAUDE.md 2>/dev/null
d=$(dirname "$d"); done
printf '@AGENTS.md\n' >> CLAUDE.md Test: the loop lists every CLAUDE file in the folder and every folder above it. Fix: delete the file if it is scratch, or, if it is a real CLAUDE.md, append the import line in the last command so it pulls AGENTS.md in, which is the pattern the docs now recommend for sharing one file across tools. If you want both files to load, set Project instructions to “CLAUDE.md and AGENTS.md” in /config.
Cause 2: You are on 2.1.277 to 2.1.280 with telemetry off
The AGENTS.md feature shipped behind a remote flag, and for four builds that flag defaulted to off whenever telemetry was disabled, including on Bedrock, Vertex and behind an LLM gateway. Przemysław Szypowicz found it with a canary of his own, and an Anthropic engineer replied in the same Hacker News thread that morning that it was “a rollout artifact” and already fixed. The fix shipped as 2.1.281 that evening.
claude --version
claude update Test: run the first command and check you are past 2.1.281. Fix: run the second.
Cause 3: Your rule says globs:, and Claude Code only reads paths:
Cursor scopes a rule with globs: and alwaysApply:. Claude Code reads exactly one frontmatter key, paths:, and ignores every other key without an error. A rule written with globs: therefore has no scope at all, so it loads at launch, on every session, for every file. In our canary test the globs: rule answered before Claude had read anything; the same rule with paths: answered only after Claude read a file it matched.
We found this one in our own kit. The script that writes Claude Code rules copied globs: straight from the master file, and wrapped each value in two layers of quotes for good measure, so all fourteen rules, including the eleven meant to be scoped, were loading on every session. The fix was one key.
grep -l '^globs:' .claude/rules/*.md Test: the command prints every rule file still using Cursor’s key. Fix: rename the key and give it plain strings, one per line, like this:
---
paths:
- "src/lib/ai/**"
- "src/components/ai-assistant/**"
--- Cause 4: Path rules fired only on Read until October 2
Before 2.1.288, a rule scoped with paths: loaded when Claude read a matching file, and stayed out when Claude wrote or edited one. Claude could create src/lib/ai/tools.ts from scratch and never see the rule for src/lib/ai/**. Test: the version again. Fix: update, or until you can, ask Claude to read a file in the folder before it writes one.
Cause 5: The import is quoted, or sits inside a code block
A CLAUDE.md can pull in other files with @path on its own line, up to four hops deep, relative to the file that contains it. Two things break it silently: a path wrapped in quotes is not imported at all, and anything inside a code span or a fenced block is skipped. Imports also do not save context; the imported file loads at launch like everything else.
@docs/conventions.md Test: put the canary in the imported file. Fix: a bare path on its own line, as above.
Causes 6–8: It Loaded and Was Ignored Anyway
The canary came back, so the file is in the context. These three are about what the model does with it, and all three apply to Cursor as much as to Claude Code.
Cause 6: The rule fights the model’s default
In the Harness-IF benchmark, every one of twelve frontier models followed an instruction between 3.6 and 7.4 points less often when it opposed what the model would have done anyway (Harness-IF, August 2026). “Every query includes organizationId in its WHERE clause”, the rule from our own database rule file, is an against-prior rule, because the model’s default is to query by record id alone.
Test: remove the rule, ask Claude how it would do the task, and see whether its default is the thing you are forbidding. Fix: pair every prohibition with the alternative, which our AGENTS.md guide shows in detail, and for the rules that must hold, read cause 9.
Cause 7: It is a style preference, and only “do not” rules move behaviour
A large study of public rule files found that random rules improved a coding agent’s pass rate exactly as much as expert-curated ones, 13.8 points either way, and that every rule which helped on its own was a negative constraint while every rule that hurt was a positive directive (Guardrails Beat Guidance, April 2026). Pass rates stayed flat from zero rules to fifty, so adding more is not the answer either.
Test: count your “always” and “prefer” lines against your “never” lines. Fix: keep the nevers, and hand the style preferences to a formatter or a linter, which enforce them for free.
Cause 8: It lives in a skill the model never opened
Vercel’s evals found the agent never invoked the relevant skill in 56 percent of cases, while the same content placed in an AGENTS.md index was used every time (Vercel, January 2026). Dan Luu saw the same with Codex in September: a third-party testing skill the agent frequently never opened, and the runs that skipped it scored better. Claude loads a skill’s body only when it decides to use that skill, so a rule placed there is absent most of the time.
Test: ask Claude which skills it has read this session. Fix: a rule that must hold every time goes in CLAUDE.md or a path rule; the skill keeps the how-to.
Causes 9–10: It Was Never Enforceable, or It’s Obsolete
The last two are about the rule itself.
Cause 9: It is a “never” with nothing behind it
Anthropic’s docs say Claude treats CLAUDE.md and memory “as context, not enforced configuration”. A study of 481 public CLAUDE.md files found that 4.4 percent of their security rules had a built-in control behind them (When “Do Not” Is Not Deny, August 2026). The author calls CLAUDE.md “a write-only channel”: you write the rule and get no signal about whether it held.
The controls that do hold are a deny rule in .claude/settings.json (or settings.local.json for just you) for a command or a file, and a PreToolUse hook that exits 2 for an edit; the primitives guide has the hook script. Two cautions from the hooks reference: a hook that exits 1, or whose script path is mistyped, lets the action through, and since October 1 a Claude Mod, a plugin that runs inside Claude Code and can approve tool calls, can approve a call that a hook blocked.
{
"permissions": {
"deny": ["Edit(./.env*)", "Bash(git push *)"]
}
} Bash patterns match the start of the command, so the rule above blocks every push, and a narrower git push --force * would miss git push -f. Test: on a throwaway branch, ask Claude to do the forbidden thing. Fix: the deny rule above for commands and files, a hook for everything else, and a CI check for anything that must hold at merge.
Cause 10: Nothing is wrong, and the rule is obsolete
Thariq Shihipar, who works on Claude Code, said in September that “in the limit, Claude.md goes away”, that it might already be better to start a project without one, and that a running log of old failure modes will “over constrain Claude” (Latent Space, September 29, 2026). Every rule was written to stop a mistake a particular model made at the time, and the model you run today may not make it.
Test: /doctor prompt-audit, added in 2.1.283, flags instructions written for older models; or disable the rule for a week and watch. Fix: delete it.
All Ten in One Table
Bookmark this one.
| Cause | Test | Fix |
|---|---|---|
| 1 Stray CLAUDE.local.md | List CLAUDE files here and in every parent | Delete it, or append @AGENTS.md |
| 2 Build 277 to 280 | claude --version | claude update |
| 3 globs: not paths: | grep -l '^globs:' on the rules | Rename the key |
| 4 Pre-2.1.288 path rules | Version | Update; read before write until then |
| 5 Quoted import | Canary in the imported file | Bare @path, own line |
| 6 Against the default | Ask what Claude would do without the rule | Prohibition plus alternative |
| 7 Style rule | Count always vs never lines | Keep nevers; linter for the rest |
| 8 Lives in a skill | Ask which skills were read | Move it to CLAUDE.md or a path rule |
| 9 No control behind it | Ask Claude to break it on a branch | Deny rule, hook, CI |
| 10 Obsolete | /doctor prompt-audit | Delete it |
Where the Rule Belongs
Most of the ten come from a rule in the wrong place, so here is the placement in one paragraph. Conventions that apply everywhere belong in AGENTS.md, with CLAUDE.md as the one-line import. Conventions for one part of the tree get a rule with paths:. Procedures you run on purpose are skills. Anything that must hold no matter what the model thinks needs a deny rule, a hook, and a CI check, which the security checklist shows wired up. MEMORY.md is Claude’s notebook, stored on your machine outside the repo, and a section of our RAG post covers what Claude writes there.
In our own kit, the rules are scoped by paths: now, the review subagents get no Edit or Write tool so a reviewer cannot change what it reviews, and the gates in CI never read the markdown at all.
If you’d rather start from a Next.js foundation where the AGENTS.md, scoped rules, review subagents and CI gates above are already wired and tested, that’s the VibeReady AI Framework. See editions from $99 →
Frequently Asked Questions
Does Claude Code read AGENTS.md?
Yes, since version 2.1.277 (September 18, 2026), but only when there is no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in the working folder or any folder above it. To load both, set Project instructions to CLAUDE.md and AGENTS.md in /config. A one-line CLAUDE.md that reads @AGENTS.md is still the documented way to share one file across tools.
Does a long CLAUDE.md get ignored partway through?
No study has measured that. The 200-line limit people quote applies to auto memory's MEMORY.md, not to CLAUDE.md, which loads in full up to 4 MiB. Anthropic recommends staying under 200 lines, and a 2026 study found pass rates flat from zero rules to fifty. The ten causes in this post are what to check instead.
How do I see which instruction files Claude Code loaded?
Run /memory or /context in an interactive session; on 2.1.280 and later both list a directly loaded AGENTS.md as well as CLAUDE.md files, rules and memory. From a script, the canary test in this post is faster: put a unique word in the file and ask for it with claude -p.
Do the same causes apply to Cursor rules?
Causes six to ten do, because they are about the model, not the file. Causes one to five are Claude Code specific. Cursor scopes rules with globs and alwaysApply in .mdc files and reads AGENTS.md natively, so the file-level checks differ, but a rule that fights the model's default or lives in a skill fails the same way in both.
Is a hook enough to enforce a rule?
Inside a session, a PreToolUse hook that exits 2 is the strongest control Claude Code offers, but it fails open: an exit code of 1 or a mistyped script path lets the action through, and a Claude Mod (a plugin that runs inside Claude Code and can approve tool calls) can approve a call a hook blocked. For anything that must hold at merge time, pair the hook with a CI check that does not read your markdown at all.
Have more questions? See our full FAQ →