[BUG] Warm 1h prompt cache fully missed (cache_read_input_tokens = 0, 634k tokens re-written) 1.6 min after the previous request, mid tool loop — v2.1.288, Opus 5.5
What happened
In a long interactive session (Claude Code 2.1.288, claude-opus-5-5, Linux/WSL2, 1h cache TTL), a request made 1.6 minutes after the previous one read 0 tokens from the prompt cache and wrote 634,307 tokens to it. Nothing earlier in the conversation was edited by the user, the model did not change, and the 1h TTL had not elapsed.
cache_read_input_tokens = 0 means even the system prompt + tool definitions prefix missed — not the usual "collapse to the system+tools floor" pattern reported in #63930 / #91514.
Request IDs
| | request id | time (UTC) | cache_read | cache_creation (1h) |
|---|---|---|---|---|
| previous request (emits 21 parallel tool_use) | req_011CfeE3p7GNvmmw7aG1nHzQ | 2026-10-02T22:48:49 | 619,640 | 1,558 |
| miss (next request in the same tool loop) | req_011CfeEBsLDn59M8GbiXsaf8 | 2026-10-02T22:50:23 | 0 | 634,307 |
| following request | req_011CfeED3MWFdfGXAwh5L8HW | 2026-10-02T22:50:48 | 634,307 | 1,846 |
What was between the two requests (from the session JSONL)
- The assistant message of
req_011CfeE3p7…ended with 21 paralleltool_useblocks (an MCP tool,mcp__claude_ai_Google_Drive__copy_file). - 21
tool_resultrows, executed sequentially (~2–3 s each). - A
task_reminderattachment ("The task tools haven't been used recently…") and anoutput_styleattachment, injected mid tool loop, immediately before the miss.
Why this is not explained by documented behaviour
- TTL: 1h tier, 1.6-minute gap.
- Lookback window: the prompt-caching docs say "a run of consecutive
tool_useblocks counts as one position, and so does a run of consecutivetool_resultblocks, so a turn with many parallel tool calls doesn't push the previous request's entry out of the window on its own." So 21 parallel calls should not cause a miss — and a lookback miss would still leave the system/tools breakpoint readable, not 0. - Prefix invalidation (tool definitions,
tool_choice, images, thinking config): nothing visible in the transcript changed. If Claude Code altered the tools array or system prompt here (e.g. an MCP tool list refresh), it was silent.
Not a deterministic trigger on my side
In the same session, 15 other task_reminder injections mid tool loop were followed by normal cache reads (writes of 0.5k–16k). So the reminder is a correlate, not a proven cause — which is why I'm reporting it with request IDs rather than a repro. Related closed-as-stale reports with the same shape: #63930 (parallel tool turns → floor collapse), #78660 (task_reminder fired mid-tool-loop rewrites cached history). Neither was fixed; both were closed by the inactivity bot.
Impact
At a 620k-token context, one such miss bills 634k tokens at the 1h cache-write rate (2× base input) instead of a cache read (0.1× base input) — ~20× the cost of the request it replaced, and on a subscription it consumes a visible chunk of the usage limit with no user action and no explanation in the UI.
Request
- Please check server-side why
req_011CfeEBsLDn59M8GbiXsaf8missed entirely — whether the prefix Claude Code sent differed fromreq_011CfeE3p7GNvmmw7aG1nHzQ's, or the entry was evicted. - Cache management is Claude Code's job, not the user's: the user cannot place breakpoints, cannot see why a miss happened, and only learns about it from the usage meter. Claude Code should (a) not mutate the prefix mid-session, (b) place an extra breakpoint before injected reminders, and (c) surface a full cache miss in the UI (e.g. "context re-cached: N tokens, reason: …") so a user is not left guessing.
Environment
- Claude Code 2.1.288, Linux (WSL2), terminal
- Model
claude-opus-5-5,service_tier: standard, cache tier 1h - Context at the miss: ~621k tokens