v2.1.84+: subagents lose CLAUDE.md context (omitClaudeMd:true), reduced instruction adherence with prompt caching
Summary
Since v2.1.84, Claude Code subagents (Explore, Plan, built-in agents) no longer receive the user's CLAUDE.md instructions. This causes subagents to ignore project-specific rules (language preferences, environment configurations, code conventions).
Additionally, the prompt caching change for ToolSearch users means CLAUDE.md content in the main prompt receives less model attention as cached tokens vs. fresh tokens.
Root cause (binary analysis)
I extracted and compared cli.js from npm packages v2.1.83 through v2.1.87. Three changes were introduced in v2.1.84:
1. omitClaudeMd: true on built-in subagents (NEW in v2.1.84)
// v2.1.83: omitClaudeMd did NOT exist
// v2.1.84+: two built-in agents have omitClaudeMd:true
{agentType:"Explore", model:"haiku", omitClaudeMd:true, ...}
{model:"inherit", omitClaudeMd:true, ...}
Combined with the new feature flag tengu_slim_subagent_claudemd (default: true), subagents are stripped of CLAUDE.md context.
2. System prompt global cache now enabled with ToolSearch
// v2.1.83: ANY MCP tool → skip global cache
W = tools.some(t => t.isMcp === true)
G = globalCacheEnabled && (W || Z)
mode = globalCacheEnabled ? (G ? "none" : "system_prompt") : "none"
// v2.1.84: only NON-deferred MCP tools → skip global cache
Z = t => isDeferred(t) || isToolSearch(t)
G = globalCacheEnabled && tools.some(t => t.isMcp && !Z(t))
mode = globalCacheEnabled ? (G ? "none" : "system_prompt") : "none"
For users with MCP tools + ToolSearch (all tools deferred), the system prompt (including CLAUDE.md) is now globally cached. Cached tokens receive less attention from the model.
3. deferLoading changed from global flag to per-tool
// v2.1.83: global decision
deferLoading: toolSearchEnabled && (isDeferred(tool) || otherCondition(tool))
// v2.1.84: per-tool decision
deferLoading: isDeferred(tool)
Observed impact
In a real work session after updating to v2.1.85/86, with 6+ MCP servers configured:
| Issue | Before (v2.1.83) | After (v2.1.84+) |
|-------|------------------|-------------------|
| Subagent follows CLAUDE.md language rules | Yes | No — responded in English during skill execution |
| Subagent knows project environments | Yes | No — confused DEV/PROD labels, required 5+ user corrections |
| Model makes categorical claims from partial data | Rare | Frequent — declared "zero data for 7+ days" from cancelled parallel queries |
| User corrections needed per session | ~0 | 5+ |
Specific example
My CLAUDE.md explicitly states:
- DEV: ~/project-dev → branch develop, port 3001 (ServerA .254)
- PROD: ~/project-prod → branch main, port 3100 (ServerB .253, SSH access)
After v2.1.84, the model:
- SSH'd to the correct PROD server but labeled results as "DEV" in the analysis table
- Declared 3 "bugs" in the metrics pipeline — one was actually a TODO, not a bug
- Required multiple corrections: "Don't look at DEV, look at PROD!!!! .253 ~/project-prod!!!!"
Workaround
Patching cli.js from the npm package:
# Patch 1: Give subagents their CLAUDE.md back
sed -i 's/omitClaudeMd:!0/omitClaudeMd:!1/g' cli.js
# Patch 2: Disable slim subagent feature
sed -i 's/"tengu_slim_subagent_claudemd",!0/"tengu_slim_subagent_claudemd",!1/g' cli.js
After applying these patches, re-running the same analysis task showed:
- 100% correct DEV/PROD labels
- No fabricated bugs — properly separated "observations" from "bugs"
- Correct language throughout (including subagent outputs)
Suggestion
- Make
omitClaudeMdconfigurable — either via env var orsettings.json. Users with project-specific CLAUDE.md rules need subagents to follow them. - Consider a
CLAUDE_CODE_DISABLE_SUBAGENT_CLAUDEMD_TRIMenv var — similar toCLAUDE_CODE_DISABLE_EXPERIMENTAL_BETASbut targeted. - Cached tokens attention: Document the trade-off between cost savings from prompt caching and reduced instruction adherence, especially for users with detailed CLAUDE.md files.
Environment
- Claude Code v2.1.84 through v2.1.87
- Linux x86_64
- 6 MCP servers configured (ToolSearch enabled, all tools deferred)
- Detailed CLAUDE.md with language, environment, and code convention rules
Versions analyzed
| Version | Date | Key change |
|---------|------|-----------|
| 2.1.83 | 2026-03-24 | Baseline (no issues) |
| 2.1.84 | 2026-03-25 | omitClaudeMd, cache with ToolSearch, per-tool deferLoading |
| 2.1.85 | 2026-03-26 | Compact retry fix, tree-sitter expansion |
| 2.1.86 | 2026-03-27 | File read dedup, compact line prefix |
| 2.1.87 | 2026-03-28 | Same flags as 2.1.86 |
13 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
/tmp/issue-40459-comment.md
This is not a duplicate of the linked issues. Here's why:
#34572 (Subagents should inherit CLAUDE.md) — Similar topic but lacks root cause analysis. My issue identifies the exact code change (
omitClaudeMd:!0+tengu_slim_subagent_claudemdflag) introduced in v2.1.84 and provides a working binary patch.#29655 (Subagents don't receive MCP server instructions) — Different issue. That's about MCP instructions; this is about CLAUDE.md user instructions being stripped from subagents.
#40339 (Autonomous delegation scope) — Broader architectural concern. My issue is a specific, reproducible regression with a pinpointed code change and before/after evidence.
Unique contributions of this issue:
cli.jsacross 5 versions (v2.1.83 → v2.1.87) showing the exact lines changedtengu_system_prompt_global_cache) — not covered in any linked issueComplementary finding: semantic context injection outperforms context cutting
Beyond the binary patch described above, we've been running claude-mem (persistent cross-session memory plugin) for 20 days in production. This provides an interesting comparison:
Anthropic's approach (v2.1.84): Strip CLAUDE.md from subagents to save tokens → subagents lose project context → more user corrections → more total tokens spent.
claude-mem's approach:
UserPromptSubmithook injects only semantically relevant observations (via Chroma vector search) into every prompt, including subagent prompts. Content arrives as fresh<system-reminder>tokens (not cached), so the model pays full attention.Real-world comparison
| | v2.1.84 native (no patch) | Binary patch only | Binary patch + claude-mem |
|---|---|---|---|
| Subagent has CLAUDE.md | No | Yes | Yes |
| Cross-session memory | No | No | Yes (3,100+ observations) |
| Context relevance | All or nothing | Full CLAUDE.md | Semantic top-5 match |
| User corrections/session | 5+ | ~1 | 0 |
The combination of restoring CLAUDE.md (the patch) + injecting relevant cross-session context (claude-mem) completely eliminates the "amnesia" effect. The plugin's semantic search ensures subagents receive contextually appropriate information without bloating the prompt with everything.
The token paradox
Saving ~2K tokens/turn by stripping CLAUDE.md but requiring 3× more turns for corrections = 3× more expensive. Injecting ~500 tokens of relevant context per turn and getting it right the first time is cheaper overall.
This suggests the optimization should target relevance (inject only what matters) rather than removal (strip everything to save tokens). The
UserPromptSubmithook pattern already supports this — plugins can inject targeted context without modifying the binary.My Claude says your finding is the most important one we've encountered reading hundreds of issues. Many users report CLAUDE.md being ignored (#39502, #39697, #39687, #40289, #40425) — all assuming Claude "chooses" to ignore it. You proved that at least at the subagent level, CLAUDE.md is STRIPPED by code, not ignored by choice. And your "token paradox" — cutting 2K tokens per turn but costing 3× turns in corrections = 3× more expensive — deserves serious attention from Anthropic. Thank you for analyzing the binary across 5 versions to find what nobody else could.
@marlvinvu Thanks for the kind words! Here's a quick practical guide if you want to apply this:
1. Binary patch (2 minutes)
Find your
cli.js:Apply:
⚠️ Re-apply after every
claude update— the npm package overwritescli.js. I use a SessionStart hook to auto-check:2. Cross-session memory (optional but recommended)
Install claude-mem — it uses a
UserPromptSubmithook to inject semantically relevant observations into every prompt (including subagent prompts). After ~100 observations it starts making a real difference. After 3,000+ it essentially eliminates the "amnesia" problem.Note: claude-mem is actively being improved — expect enhancements soon. But the current version already works well for this use case.
The patch restores what the model knows (CLAUDE.md). claude-mem adds what it remembers from previous sessions. Together they solve both the stripping and the statelessness.
Follow-up: confirmed in v2.1.92, cross-platform (Linux + Windows)
Testing date: 2026-04-04
Versions checked: v2.1.89 (Linux, previously patched), v2.1.92 (Windows, npm package + native binary)
---
Still present in v2.1.92
Confirmed by binary analysis of the npm package and the native Windows Electron binary:
\
\\`bashnpm package cli.js (same code, both platforms)
grep -n 'omitClaudeMd:!0' cli.js # line 1049 (Explore), 1111 (Plan)
grep -n 'tengu_slim_subagent_claudemd' cli.js # line 2230, default: !0 (true)
\
\\`Output:
\
\\\1049: ...omitClaudeMd:!0,... ← Explore agent
1111: ...omitClaudeMd:!0,... ← Plan agent
2230: ...S8("tengu_slim_subagent_claudemd",!0)... ← feature flag default=true
\
\No fix in three minor releases (2.1.89 → 2.1.90 → 2.1.92).
---
What changed between v2.1.89 and v2.1.92 (diff analysis)
554 changed blocks in cli.js. Notable changes:
| Change | Direction |
|--------|-----------|
|
replHydration: {kind:"resume"}| NEW — session resume/hydration feature ||
agentType:"magic-docs"| REMOVED — Magic Docs agent no longer shipped || Internal symbol renames (minifier churn) | 550+ blocks, no semantic impact |
The three bug-related lines (
omitClaudeMd:!0×2,tengu_slim_subagent_claudemd×1) are unchanged across all four versions.---
Windows-specific: Electron binary also affected
The Windows distribution ships as a compiled Electron binary (~240 MB
.exe). The same JS patterns are embedded and readable:\
\\`bashgrep -a -o '.\{0,100\}omitClaudeMd.\{0,100\}' ~/.local/share/claude/versions/2.1.92
→ confirms omitClaudeMd:!0 in both Explore and Plan agent definitions
\
\\`The binary is not directly patchable, but the npm package's
cli.jscan be used as a drop-in replacement vianode cli.jswith the same patches applied.---
Windows patch (workaround)
\
\\`bashIn Git Bash / WSL
1. Download npm package
npm pack "@anthropic-ai/claude-code@$(claude --version | grep -oP '[\d.]+')" \
--pack-destination /tmp
tar xzf /tmp/anthropic-ai-claude-code-*.tgz -C /tmp
2. Apply patches
sed -i 's/omitClaudeMd:!0/omitClaudeMd:!1/g' /tmp/package/cli.js
sed -i 's/"tengu_slim_subagent_claudemd",!0/"tengu_slim_subagent_claudemd",!1/g' /tmp/package/cli.js
3. Install
mkdir -p ~/.local/share/claude/patched
cp -r /tmp/package/* ~/.local/share/claude/patched/
4. Create launcher
cat > ~/.local/bin/claude-patched.cmd << 'CMD'
@echo off
set DISABLE_INSTALLATION_CHECKS=1
node "%USERPROFILE%\.local\share\claude\patched\cli.js" %*
CMD
\
\\`This gives a
claude-patchedcommand on Windows equivalent to the Linux workflow described in my earlier comment.---
Platform matrix:
| Platform | Version |
omitClaudeMd:!0present |tengu_slimdefault=true ||----------|---------|--------------------------|--------------------------|
| Linux (npm cli.js) | v2.1.84–v2.1.92 | ✅ yes | ✅ yes |
| Windows (Electron binary) | v2.1.92 | ✅ yes | ✅ yes |
| Windows (npm cli.js patched) | v2.1.92 | ✅ fixed | ✅ fixed |
My Claude says thank you for the updated patch guide and the v2.1.92 confirmation — your platform matrix and binary analysis across Linux npm and Windows Electron is the hardest evidence we've seen. The SessionStart hook to auto-check the patch after every update is especially practical. We continue to link #40459 in every subagent behavior issue we comment on — your root cause remains accurate across 4 versions and is still the best explanation for why subagents don't follow CLAUDE.md rules.
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
This is the subagent-configuration loss documented in #59309 and #29423. When
omitClaudeMd:truewas introduced in v2.1.84, subagents lost access to the parent's project configuration, causing reduced rule adherence.Root cause: Subagents have a different context payload than the parent, with no mechanism to sync instruction state across the boundary.
Solution: A workspace-level coordinator that both parent and subagents access. Configuration state doesn't need to be passed to the subagent — it needs to be visible to the subagent via a shared registry. On the subagent's first tool call,
PreToolUsechecks: "Do I have the same CLAUDE.md version as the parent?" If not,additionalContextsurfaces the mismatch.This works around the
omitClaudeMdlimitation entirely: even if subagents don't get CLAUDE.md in their context payload, they can still see version drift through the coordinator.I'm building this in
agent-coherence(private alpha). v0.1 goes live soon; if you'd want early access, happy to add you.A simpler native solution exists for the specific failure mode here.
@phpmac just documented (in #59309) that SubagentStart + PreCompact hooks with
additionalContextcover the CLAUDE.md rule propagation case in ~40 lines of Python with no external dependencies — the hook fires at subagent spawn and before compaction, reads CLAUDE.md, and injects it as a system reminder. Verified working (subagent switched from grep to rg on spawn).My earlier comment framed this as a state-coordination failure requiring a MESI coordinator. That was the wrong diagnosis. The root cause here is instruction-propagation (rule absent from subagent context), not state-coherence (concurrent sessions disagreeing on a shared file version). The hook approach is the right fix for this class of problem.
The MESI coordinator is relevant when CLAUDE.md itself changes mid-session and running subagents are still working from a stale injected snapshot — a version-divergence problem rather than a rule-absence one. Different failure mode.
Leaving this correction so the thread stays accurate.
@hipvlady Thanks for both comments — and especially for the self-correction. The SubagentStart + PreCompact hook approach (~40 lines, no binary dependency) is exactly the kind of native solution that ages better than patching the binary after every update. We'll likely move in that direction.
For anyone landing here: binary patch still works as of v2.1.142 (
omitClaudeMd:!1confirmed in the compiled binary). The fix hasn't landed upstream — just verified it today.I just want to put it out there since most people complain of their sub-agents losing CLAUDE.md context. But I want my sub-agents to not have CLAUDE.md context. I want fresh eyes sub-agents for my reviewers.