[BUG] -p --resume from a git repo: any `git status` change between turns invalidates the entire prompt cache (full-prefix re-creation)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The CLI embeds dynamic per-machine sections — including git status output — into the system prompt at every spawn. For headless spawn-per-turn integrations (claude -p --resume <id> launched fresh each turn by a host process), any change to the repo's status output between turns (a commit, a new untracked file, a deleted marker) changes the system prompt. The system prompt sits ahead of the entire conversation, so the whole cached prefix is invalidated: cache_read_input_tokens collapses to the ~21k shared-boilerplate floor and the full conversation history is re-created as cache_creation_input_tokens.
Measured across one workspace's full transcript history (~/.claude/projects/<workspace>/*.jsonl): 1,407 of 16,058 API calls (8.8%) show the full-collapse signature — 161,124,671 tokens re-created in collapse events across 183 sessions. This burns subscription usage-cap headroom and adds latency; for API-key users it re-bills entire conversation histories at cache-write rates.
This is not the tool-reordering resume bug (#42338 / #34629): it reproduces with zero tools, zero MCP servers, and a one-word reply, and it is deterministic on demand via git status churn alone.
What Should Happen?
A resumed turn should serve the prior conversation from cache: at call N, cache_read_input_tokens should equal the cumulative read + creation of every prior call (the healthy signature, which holds reliably from a non-repo cwd). A change in git status output between turns should not re-bill the entire conversation history — e.g., the dynamic sections could sit behind a cache breakpoint / after the stable prefix, or be frozen to session-start values for -p --resume continuations (the model already receives fresh state via tool use).
Error Messages/Logs
No error is emitted - the failure is silent re-billing, visible only in per-call usage.
Re-run on 2.1.212 (fresh minimal repo, untracked marker flipped between resumes;
per-call usage from --output-format json):
turn1 read=21,213 create=9,203 (session created)
turn2 read=21,213 create=9,516 expected read=30,416 -> FULL COLLAPSE (prior prefix re-created)
turn3 read=30,416 create=364 expected read=30,729 -> partial re-creation
turn4 read=30,729 create=109 healthy
turn5 read=30,780 create=108 healthy
Same-day control from a NON-repo cwd, identical churn in an --add-dir'd repo: 4/4 healthy exact-prefix reads.
Steps to Reproduce
- Control (non-repo cwd): in an empty non-repo directory run
claude -p "Reply with exactly: ok" --output-format json, then 4–5 more turns with--resume <session_id>. Observe: every resume'scache_read_input_tokensexactly equals the prior cumulativeread + creation. 0/5 collapses. - Trigger (git repo cwd + churn):
git inita minimal repo (one committed README), run the same turn-1 command from inside it, then the same--resumeturns — but between each turn create or delete an untracked marker file (any change togit statusoutput). - Observe: resumes following a status change collapse —
cache_readfalls to the ~21k floor andcache_creationre-does approximately the entire prior cumulative total. 3/5 collapsed on 2.1.207; 1 full collapse + 1 partial re-creation across 4 churned resumes on 2.1.212. - Collapses occur only on turns where the status output actually changed since the prior spawn — matching the intermittent ~9–15% rate observed in production traffic.
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.212 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Non-interactive/CI environment
Additional Information
- Auth/platform detail: first-party Anthropic backend via Claude Max subscription OAuth login — no API key, no gateway/proxy. Windows 11, native binary install (not npx).
- Models: minimal repro on Haiku (model-independent, keeps repro cost trivial); the same collapse signature is observed with Opus across production traffic in the measured corpus.
--exclude-dynamic-system-prompt-sectionsmakes it WORSE for this use-case: it moves the dynamic sections into the first user message, which regenerates on every resume — 5/5 collapses on the same repro.- Related but distinct: #42338 and #34629 (resume cache invalidation attributed to
deferred_tools_deltatool reordering, v2.1.69+). This mechanism needs no tools at all; the trigger is the git-status section of the system prompt. - Workaround verified locally: spawn the subprocess from a stable non-repo cwd (removes the git-status section entirely) with repo access preserved via
--add-dir <repo>— 0/4 collapses with deliberate status churn in the add-dir'd repo. Only viable for sessions that don't require a repo cwd.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗