[BUG] -p --resume from a git repo: any `git status` change between turns invalidates the entire prompt cache (full-prefix re-creation)

Status Open
Reported on v2.1.212
Maintainer reply None cached
Activity 1 comment · opened Jul 18, 2026

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

  1. 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's cache_read_input_tokens exactly equals the prior cumulative read + creation. 0/5 collapses.
  2. Trigger (git repo cwd + churn): git init a minimal repo (one committed README), run the same turn-1 command from inside it, then the same --resume turns — but between each turn create or delete an untracked marker file (any change to git status output).
  3. Observe: resumes following a status change collapse — cache_read falls to the ~21k floor and cache_creation re-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.
  4. 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-sections makes 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_delta tool 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.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗