Skip to content

[Bug] Per-session console URL in the Bash tool description defeats cross-session prompt-cache reuse #82229

Description

@Gunther-Schulz

What's Wrong?

Claude Code embeds the per-session console URL inside the Bash tool's description:

- Command output … <https://claude.ai/code/session_01Rq9o…> (appears twice in the description text)

Tool definitions are part of the cached prompt prefix, at its very front. Because this URL is unique per session, tools[] differs byte-wise between any two sessions that are otherwise identical — same repo, same settings, same system prompt. Consequences:

  • A new session can never warm-start on the prompt cache of a previous one, even though everything else in the ~20k-token prefix (tools + system prompt) is byte-identical. Every session pays a full cache write for a prefix that differs only by its own URL.
  • Headless runs (claude -p) in CI/automation pay this on every invocation.

This is the CLI sibling of #27786 (Agent SDK: random UUID in the Bash tool description, closed/fixed). The SDK fix did not carry over to the CLI's session URL.

Environment

Claude Code 2.1.220, linux. Verified by diffing captured /v1/messages bodies from two sessions through a local proxy: the Bash description is the only divergence carrying session identity; our proxy strips it (toolFingerprint normalization) precisely because of this.

What Should Happen?

Tool descriptions should be byte-stable across sessions. The session console URL belongs outside the cached prefix — e.g. in a tail system-reminder (like other per-session context CC already injects), or omitted from the model-visible description entirely; the model rarely needs its own console URL, and when it does, a stable placeholder ({{SESSION_URL}}) resolved client-side would keep the bytes fixed.

Steps to Reproduce

  1. Capture request bodies from two CC sessions in the same repo (any MITM proxy).
  2. Diff the first request's tools[] between the sessions.
  3. The Bash tool description differs only by the embedded https://claude.ai/code/session_… URL — and that difference sits inside the cached prefix.

Related work: we mitigate several prefix-invalidation classes in a proxy fork (see cnighswonger/claude-code-cache-fix#272, #273, which address the mid-history reminder rewrites of #76606 and the tools[] mutation of #81967 respectively).

🤖 Generated with Claude Code

Update (same day): the capture + replay toolchain used for the verification above is now PR'd upstream (cnighswonger/claude-code-cache-fix#275, #276), so the reproduction steps are runnable end-to-end on anyone's own traffic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions