Why your nested CLAUDE.md or path-scoped rule never loaded
Claude Code does not load every instruction file at launch. A nested CLAUDE.md is a file in a subdirectory below the directory where you started Claude Code. A path-scoped rule is a markdown file under .claude/rules/ with a paths: field, meant to apply only to matching files. Both wait for Claude to touch the right file. When that touch never happens, neither does the load, and nothing in the session says so. The model does not announce a missing rule; it continues with the root instructions it has.
Checked against each tool's documentation on 26 October 2026.
Status, 28 October 2026: the docs say a Bash cat or head on a single file counts as a read for both nested files and path-scoped rules. On v2.1.293 or later that is true for a plain single-file cat, head, tail, sed -n or grep; before 2.1.293, only native file tools loaded a path-scoped rule. Piped reads, cd-prefixed chains, Bash edits such as sed -i and heredocs, and the other access methods still miss (#90450, #88565). Both issues were open on this date. Read remains the reliable trigger.
Yes, Claude Code supports nested CLAUDE.md#
The question comes up because the answer is "yes, but not at launch". At startup Claude Code loads CLAUDE.md and CLAUDE.local.md from the working directory and every directory above it, concatenated from the filesystem root down to where you started. Within one directory, CLAUDE.local.md is appended after CLAUDE.md.
A file below the working directory is different. It loads on demand, when Claude reads, writes, or edits another file in that subdirectory. The docs also count a Bash cat or head on a single file as a read.
Path-scoped rules work the same way. A rule without a paths: field loads at launch. A rule with paths: waits until Claude uses Read, Write, or Edit on a matching file, or a qualifying Bash read. Rules in a nested .claude/rules/ directory load on demand too.
Seven reasons the file never loaded#
1. The session started somewhere else#
If you launch in the repository root, packages/api/CLAUDE.md is a nested file. If you launch in packages/api, the same file is a launch file and should appear in /context. If you launch in apps/web, the packages/api file is not under your working directory at all.
This is why the same rule works in one terminal and not another. The file did not change. The starting directory did.
2. Claude reached the file through the wrong tool#
The docs describe a tool-agnostic trigger. The first measurements were on 2.1.250 and 2.1.238, before the fix. In #90450, 27 access methods were tested against directories with their own CLAUDE.md; Read was the only one that loaded the nested file. cat, head, sed, grep, find, a Python one-liner, ls, and even Write and Edit did not. Rechecks on 2.1.294 and 2.1.296 found that a plain single-file cat, head, tail, sed -n or grep with a match does load, while piped reads and cd-prefixed chains still do not. In #88565, a path-scoped rule loaded through Read, Write, and Edit, but a Bash edit never injected it; a 2.1.296 recheck found the same for every Bash write.
The practical rule is simple: if you need the file loaded, open a file in that directory with the Read tool once. For a path-scoped rule, open a file that matches its paths: patterns. On v2.1.293 or later a plain single-file cat, head, tail, sed -n or grep also works, but a piped read, a cd-prefixed chain, a glob, a recursive search, or a Bash edit does not; Read remains the reliable trigger.
3. Auto mode sent the work through Bash#
Auto mode is a permission mode where a separate classifier model reviews actions and approves routine ones without prompting you. The reports measured it injecting an instruction to do file work through Bash wherever possible: read with cat, head, or sed, search with grep and find, edit with sed or heredocs, and use Read, Edit, or Write only when Bash could not. A report says bypass permissions carries the same steering. On v2.1.293 or later the plain single-file read part can load the file; the Bash edit part still cannot.
That still points away from the reliable trigger for edits. On v2.1.293 or later a plain single-file read can load the file, but piped reads, cd-prefixed chains, sed -i, heredocs, and the other Bash writes still miss, so a session that edits through Bash gets no nested file and no path-scoped rule. Switch to manual or accept-edits mode, or ask Claude to open the file with Read before it starts editing. Do it before the first change, not after.
4. The path pattern did not match#
A paths: value is a list of glob patterns, filename patterns with * and **, relative to the rule's base directory: the directory containing .claude for project rules, the session's primary working directory for user rules. src/**/* matches everything under src/; *.md matches only the project root.
A rule that seems dead may be watching a path Claude never touched. It may also be malformed. paths is the only frontmatter field Claude Code reads; if the YAML between the --- markers does not parse, Claude Code ignores the frontmatter and loads the rule as if it had no paths: field. That makes it load everywhere, not nowhere. Run claude --debug to see the parse error. A paths list also has a budget of 1,000 expanded patterns and 4 MiB; patterns over it are used unexpanded and may match nothing.
5. The file is outside the set Claude Code reads#
claudeMdExcludesskips files by absolute path or glob. It can be set at user, project, local, or managed level, and arrays merge. It cannot exclude a managed CLAUDE.md.--setting-sourcesthat leaves outprojectskips project rules.--add-dirgives Claude access to another directory but does not load that directory's CLAUDE.md by default. SetCLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1if you want those files too.- A
.claude/rules/symlink whose target is outside your working directory is treated as an external import. It does not load until you approve external imports, and after that only linked rules without apaths:field load.
6. AGENTS.md is being shadowed#
If your instructions are in AGENTS.md, Claude Code reads it only when there is no CLAUDE.md, .claude/CLAUDE.md, or CLAUDE.local.md in the working directory or above it. A subdirectory's AGENTS.md loads when Claude opens a file there with Read, and only if that subdirectory has none of the three CLAUDE.md files. To read both, set Project instructions to claude-md-and-agents-md, or import AGENTS.md from a CLAUDE.md. An AGENTS.md read through the setting does not fire InstructionsLoaded.
7. The file is too large for a lazy load#
A subdirectory CLAUDE.md, a nested .claude/rules/ file, or a path-scoped rule that loads on demand has a per-file size limit. For a 200K context window, the working text the model can see at once, it is 40,000 characters; for a 1M window, 200,000 on Opus 4.6 and Sonnet 4.6 and 150,000 on later models.
Over the limit, Claude receives only the start of the file, ending with a note telling it to read the rest. Until it does, the later instructions are not in context. Run wc -m and compare. A project-root CLAUDE.md over 4 MiB is skipped entirely.
If it loaded, but an edit did not apply#
Project-root and user-level CLAUDE.md files are read once at session start and held in memory. A mid-session edit does not change the copy Claude is using; it loads on the next /clear, /compact, or restart. The prompt-caching documentation explains why: prompt caching, the reuse of the unchanged start of each request, is why an edited CLAUDE.md waits for the next session, /clear, or /compact.
A nested file or path-scoped rule is different. An edit before it loads takes effect. After it loads, the content is conversation history, so a later edit does not retroactively change it. Restart or /clear if the change matters. If you create a new nested file during a session, create it from your shell, then ask Claude to read a file in that subdirectory.
How to prove what loaded#
`/context` shows launch files, not lazy ones#
Run /context and look under Memory files. It lists the CLAUDE.md and CLAUDE.local.md files that loaded at launch. A nested file in a subdirectory does not appear there, because it loads on demand rather than at launch. Its absence is not proof that it is broken. When a nested file or path-scoped rule does load, a Loaded line with its path appears in the terminal. That line is the moment to watch for.
The `InstructionsLoaded` hook is the direct check#
The InstructionsLoaded hook runs whenever a CLAUDE.md or .claude/rules/*.md file loads. It fires at session start for eager files and again for nested files and matching rules. It cannot block or change a load; it is for observability.
Add it to .claude/settings.json:
{
"hooks": {
"InstructionsLoaded": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '[.load_reason, .memory_type, .file_path, (.trigger_file_path // \"-\")] | @tsv' >> .claude/instructions.log"
}
]
}
]
}
}Each line in .claude/instructions.log names the reason (session_start, nested_traversal, path_glob_match, include, or compact), the scope, the file, and the file whose access triggered a lazy load. If jq is not installed, use cat >>.claude/instructions.log and read the raw JSON.
You can filter with a matcher on load_reason. "matcher": "nested_traversal|path_glob_match" logs only lazy loads. If the log stays empty after Claude edits a file in the subdirectory, the trigger did not fire.
`claude --debug` and `wc -m` show the other failures#
Run claude --debug when a rule does not behave as expected: a malformed paths: block is reported there. For a file that loads but seems to lose its ending, count characters:
wc -m packages/api/CLAUDE.mdCompare with the limit for your window, then trim the file or split it into rules files that each stay under the limit.
What to do instead#
If the rule must apply every time, move it to the project-root CLAUDE.md. That file loads at launch and is re-injected after compaction, the pass that replaces older turns with a summary when the window fills. A path-scoped rule is the wrong tool for a rule that must never be missed.
If the rule is genuinely local, keep the nested file small and open a matching file with Read at the start of work. You can also put a one-line pointer in the root CLAUDE.md, such as "Before editing under packages/api/, read packages/api/CLAUDE.md." The pointer is still a model instruction, not a guarantee, but it gives the trigger a reason to happen.
For a hard constraint, use something the model does not decide: a PreToolUse hook to block a tool call, or a permission deny rule. The memory documentation recommends hooks for instructions that must run at a specific point, such as before every commit. If you use auto mode, switch modes for the part of the session that needs nested instructions.
Where to go next#
For the rest of the set, see the Claude Code guides hub.
- How long can CLAUDE.md be? — the 4 MiB skip, the on-demand character caps, and what arrives when a file is over them.
- Claude Code auto memory covers the other store Claude reads at startup, and why its index can be clipped.
- What a Claude Code subagent can and can't see explains which instruction files reach a subagent.
- Why Claude Code keeps asking for permission covers the enforcement layer when a rule must be absolute.
- Persistent memory for Claude Code and Codex puts instruction files in the wider choice of memory mechanisms.
- Instruction files, skills and memory compares what each agent reads.