v2.1.84+: subagents lose CLAUDE.md context (omitClaudeMd:true), reduced instruction adherence with prompt caching

Status Closed — not planned
Reported on v2.1.83
Maintainer reply None cached
Activity 12 comments · opened Mar 29, 2026 · closed May 15, 2026

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:

  1. SSH'd to the correct PROD server but labeled results as "DEV" in the analysis table
  2. Declared 3 "bugs" in the metrics pipeline — one was actually a TODO, not a bug
  3. 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

  1. Make omitClaudeMd configurable — either via env var or settings.json. Users with project-specific CLAUDE.md rules need subagents to follow them.
  2. Consider a CLAUDE_CODE_DISABLE_SUBAGENT_CLAUDEMD_TRIM env var — similar to CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS but targeted.
  3. 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 |

View original on GitHub ↗

13 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/34572
  2. https://github.com/anthropics/claude-code/issues/29655
  3. https://github.com/anthropics/claude-code/issues/40339

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

yurukusa · 5 months ago

/tmp/issue-40459-comment.md

alessandropcostabr · 5 months ago

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_claudemd flag) 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:

  1. Binary-level diff of cli.js across 5 versions (v2.1.83 → v2.1.87) showing the exact lines changed
  2. Identified 3 specific code changes (not just symptoms)
  3. Reproducible before/after comparison with the same analysis task
  4. Working workaround (2 sed commands on cli.js)
  5. Interaction with prompt caching (tengu_system_prompt_global_cache) — not covered in any linked issue
alessandropcostabr · 5 months ago

Complementary 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: UserPromptSubmit hook 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 UserPromptSubmit hook pattern already supports this — plugins can inject targeted context without modifying the binary.

marlvinvu · 5 months ago

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.

alessandropcostabr · 5 months ago

@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:

# Usually at:
ls $(npm root -g)/@anthropic-ai/claude-code/cli.js
# or:
ls $(which claude | xargs dirname)/../lib/node_modules/@anthropic-ai/claude-code/cli.js

Apply:

CLI_JS="$(npm root -g)/@anthropic-ai/claude-code/cli.js"

# Restore CLAUDE.md to subagents
sed -i 's/omitClaudeMd:!0/omitClaudeMd:!1/g' "$CLI_JS"

# Disable slim subagent flag
sed -i 's/"tengu_slim_subagent_claudemd",!0/"tengu_slim_subagent_claudemd",!1/g' "$CLI_JS"

⚠️ Re-apply after every claude update — the npm package overwrites cli.js. I use a SessionStart hook to auto-check:

{
  "hooks": {
    "SessionStart": [{
      "matcher": "startup",
      "hooks": [{ "type": "command", "command": "claude-patch-check 2>/dev/null || true", "timeout": 30 }]
    }]
  }
}

2. Cross-session memory (optional but recommended)

Install claude-mem — it uses a UserPromptSubmit hook 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.

alessandropcostabr · 4 months ago

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:

\\\`bash

npm 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:

\\\`bash
grep -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.js can be used as a drop-in replacement via node cli.js with the same patches applied.

---

Windows patch (workaround)

\\\`bash

In 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-patched command on Windows equivalent to the Linux workflow described in my earlier comment.

---

Platform matrix:

| Platform | Version | omitClaudeMd:!0 present | tengu_slim default=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 |

marlvinvu · 4 months ago

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.

github-actions[bot] · 3 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

hipvlady · 3 months ago

This is the subagent-configuration loss documented in #59309 and #29423. When omitClaudeMd:true was 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, PreToolUse checks: "Do I have the same CLAUDE.md version as the parent?" If not, additionalContext surfaces the mismatch.

This works around the omitClaudeMd limitation 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.

hipvlady · 3 months ago

A simpler native solution exists for the specific failure mode here.

@phpmac just documented (in #59309) that SubagentStart + PreCompact hooks with additionalContext cover 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.

alessandropcostabr · 3 months ago

@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:!1 confirmed in the compiled binary). The fix hasn't landed upstream — just verified it today.

carlsondev · 2 months ago

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.