[BUG] ToolSearch unlock invalidates prompt-cache prefix mid-session

Resolved 💬 2 comments Opened Apr 25, 2026 by s6yoho Closed May 28, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code (2.1.119)

What's Wrong?

The first time ToolSearch(select:...) unlocks a deferred tool's schema in
a session, the next request invalidates the prompt-cache prefix from the
tool registry onward. cache_creation_input_tokens on that turn equals the
entire conversation accumulated so far, not the unlocked-schema delta.

Distinct from #42309 (same mechanism on --resume, fixed v2.1.90 for the
resume path only) and from the content-drift family (#48734 / #49585 /
#40652 / #49038) — trigger here is the registry mutation itself, not byte
drift in historical messages.

Evidence

Single session, 80 deduped API turns, 97.4% overall cache_read share.
One invalidation event:

| turn | cache_read | cache_creation | note |
|-----:|-----------:|---------------:|-------------------------------------------------------|
| #24 | 67,621 | 2,066 | normal incremental growth |
| #25 | 14,756 | 62,594 | prev step: ToolSearch(select:TaskCreate,TaskUpdate) |
| #26 | 77,350 | 1,449 | back to normal |

The two unlocked schemas are a few hundred tokens combined; the 62K
cache_creation is the entire suffix re-caching. Every other large
cache_creation in the session was monotonic growth (cache_read keeps
rising), not invalidation.

Mechanism

Tool definitions sit right after the system prompt. Unlocking a deferred
tool changes the tool registry block, so the cache prefix from that byte
onward stops matching and the entire suffix (system-prompt tail + tools +
message history) is rewritten at the cache-write rate. Cost scales linearly
with session length at unlock time.

Steps to Reproduce

  1. Run a session long enough to accumulate non-trivial cache_read.
  2. Have the model call ToolSearch(select:<any-deferred-tool>) for a tool

not yet unlocked in this session.

  1. Observe the next request: cache_creation_input_tokens ≈ full

conversation prefix up to that point; cache_read_input_tokens collapses
to roughly the tools-block size.

What Should Happen

Unlocking a deferred tool should not invalidate prefix cache for content
unrelated to that tool's schema (system prompt, message history). The
incremental schema bytes should be the only cache_creation cost.

Claude Code Version

2.1.119

Platform

Anthropic API

Operating System

Other Linux

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗