[BUG] Prompt Cache Invalidation on Session Resume: Tool-Use Content Not Cached, Plugin State Changes Cause Full User Content Rewrite
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?
Summary
Claude Code's prompt caching implementation fails to cache tool-use content (Read operations) across session resumes, and plugin state changes during active sessions trigger complete rewriting of cached user content. This particularly impacts users employing context-window optimization strategies (frequent plugin enable/disable to manage token costs).
Testing Environment
- All tests conducted within 5-minute cache TTL window
- Operations: C+C to exit session →
claude --resume "sessionid"→ Read tool invocations - Resume intervals: 5 seconds to 3 minutes (no variance in behavior)
Observed Behavior
Tool-Use Content Caching Failure
Cache metrics across various transcript compositions (within 5min TTL):
| Transcript Composition | Tool Reads | Before Resume | After Resume | Delta | Hit Rate Change |
|---|---|---|---|---|---|
| Baseline | 0 | Cache: 60K | Write: 2-3K, Read: 60K | +2-3K | 99% → 96% |
| Minimal reads | 2-3 | Cache: 65K | Write: 2K, Read: 65K | +2K | 99% → 96% |
| Moderate reads | 5-7 | Cache: 70K | Write: 4-5K, Read: 60K | +4-5K | 99% → 92% |
| Heavy reads | 20+ | Cache: 117K | Write: 91K, Read: 19K | +91K | 99% → 17% |
Critical observation: Cache reads decrease while writes increase. In heavy-read sessions, 98K of previously-cached content is not retrieved; instead, 91K of new tokens are written to cache, indicating complete re-evaluation/rewriting of tool-use content section.
Plugin State Changes Trigger Full User Content Cache Rewrite
When plugin state changed mid-session (enable/disable via /plugin command), systematic cache invalidation was observed across multiple test cycles:
Plugin Enable (Disable → Enable)
| Test | Initial Cache Read | Final Cache Read | Cache Write | Invalidated | Preserved |
|---|---|---|---|---|---|
| Enable Test 1 | 113K | 0K | 115K | 113K | 0K |
| Enable Test 2 | 123K | 19K | 105K | 104K | 19K |
Pattern: Enable operations wipe cache (sometimes completely to 0K, sometimes to 19K baseline), then rewrite 100-115K of user content.
Plugin Disable (Enable → Disable)
| Test | Initial Cache Read | Final Cache Read | Cache Write | Invalidated | Preserved |
|---|---|---|---|---|---|
| Disable Test 1 | 115K | 19K | 97K | 96K | 19K |
| Disable Test 2 | 122K | 19K | 103K | 103K | 19K |
Pattern: Disable operations consistently preserve 19K (system context only) and rewrite 96-103K of user content.
Critical Finding: System Context Preservation
19K preserved = System Prompt (3.6K) + System Tools (~15.3K) — only system context survives plugin state changes; all user content and tool-use is rewritten.
System Tools Size Change Does Not Correlate
- Plugins disabled: System tools: 17K
- Plugins enabled: System tools: 16.4K (smaller, yet cache still invalidated)
Implication: Cache invalidation is not driven by system tools size changes; the issue involves content differences or cache validation key changes in plugin definitions, not simple size deltas.
Asymmetric Behavior Confirms Bug
Enable and disable handle cache invalidation differently, with enable showing more aggressive cache wiping, indicating a bug in cache validation logic during plugin state transitions.
Technical Analysis
What Remains Stable (Not Invalidating Cache)
- System prompt hash
- System tools definitions
- Session duration between closes (5s to 3min: identical behavior)
- Memory files (insufficient test data, but statistically stable)
What Invalidates Cache
- Tool-use content sections (Read tool outputs) — proportional to read count
- Plugin state changes — complete user content cache rewrite
- System prompt regeneration — affects all downstream cache validation
Root Cause Hypothesis
Tool-use content (transcript sections containing Read tool responses) either:
- Is excluded from prompt caching entirely, or
- Uses a different cache validation key that differs between resumes, or
- Is included in a cache segment that is invalidated by system prompt changes
Plugin state changes likely trigger a system context rebuild that cascades to user content re-evaluation.
Impact Assessment
Use Case 1: Frequent Session Exits/Resumes Within TTL
- Likelihood: Low (most users don't exit/resume frequently within 5min window)
- Impact: 2-91K token waste per resume depending on session size
- Severity: Moderate (edge case, but compounding for heavy CLI users)
Use Case 2: Context Optimization via Plugin Management
- Likelihood: HIGH — users managing context windows to reduce costs frequently enable/disable plugins mid-session
- Impact: Complete user content cache rewrite on every plugin state change
- Severity: CRITICAL — affects all users employing cost-optimization strategies
Test Data Summary
Session Resume Tests (within 5-minute TTL)
- Total resume tests: 15+ sessions
- Small transcripts (0-7 reads): Consistent 2-5K write overhead
- Large transcripts (20+ reads): 91K write, 17% hit rate (complete tool-use invalidation)
- Resume timing: 5 seconds to 3 minutes — no correlation with invalidation pattern
Plugin State Change Tests
- Total plugin state transitions tested: 4 cycles (2 enable, 2 disable)
- Plugin enable: 100-115K user content rewrite (0-113K previously cached dropped)
- Plugin disable: 96-103K user content rewrite (19K system context always preserved)
- System tools size variance: 17K (disabled) vs 16.4K (enabled) — size change did NOT prevent cache invalidation
- Asymmetric behavior: Enable and disable handle cache invalidation differently, confirming implementation bug
Key Findings
- Tool-use (Read operations) not cached — proportional to large content rewrite on resume
- Plugin state changes trigger catastrophic cache loss — affects every user managing context
- System context (19K) preserved on disable only — enable operation completely wipes cache before rebuilding
- Size-based cache invalidation hypothesis rejected — system tools size decreased but cache still invalidated
#What Should Happen?
Expected Behavior
- Tool-use content cached in initial session should be reused without modification on resume
- Plugin state changes should not invalidate cached user content (only system context)
- Cache hit rates should remain >95% on resume regardless of tool-use volume or plugin changes
Workaround
None identified. Users cannot prevent plugin-triggered cache invalidation without abandoning mid-session plugin management.
Steps to Reproduce
# Session 1: Build transcript with tool use
claude --resume "sessionid" # or new session
# Execute: read file1.txt, read file2.txt, ... (multiple reads)
# Execute: /plugin enable some-plugin (or disable)
# C+C exit
# Session 2: Observe cache metrics
claude --resume "sessionid"
# Observe: Cache Write increases significantly, Cache Read decreases, Hit Rate drops
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.49 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
_No response_
This issue has 12 comments on GitHub. Read the full discussion on GitHub ↗