Prompt-section cache is keyed by name only, so a subagent on a different model receives the main model's identity and cutoff
What happens
In a session where the main loop runs one model and subagents run another, the subagent's API request carries the main model's model-dependent system-prompt sections.
Captured raw request bodies (OTEL_LOG_RAW_API_BODIES) from a single session on CLI 2.1.257: the request for an Opus 5 subagent ("model": "claude-opus-5") contained
- the Fable 5.1 identity paragraph, verbatim, including "This iteration of Claude is Claude Fable 5.1",
- two "You are powered by the model named" lines, one per model,
- two knowledge cutoffs, June 2026 and May 2026,
- the model-gated "# Writing for the user" register section.
A cold claude -p --model claude-opus-5 run in the same directory, same settings, contained none of that text. So this is not configuration; it is state carried inside the session.
Why
Wvt in the 2.1.257 bundle resolves each dynamic section against a session-scoped Map keyed by section name alone:
async function Wvt(e){let n=D$();return Promise.all(e.map((r)=>r.cacheBreak||!n.has(r.name)?jvt(r.name,r.name,r.compute):Promise.resolve(n.get(r.name)??null)))}
D$() returns session.promptAssembly.sections(), and the only invalidation wired to that map (ynt) fires on worktree switch and on resume. Whichever model assembles a prompt first in the process therefore latches every model-dependent section for the life of the session. The sections whose compute reads the model are exactly the ones that go wrong: identity, knowledge cutoff, and any register section selected per model.
Suggested fix
Key the map by section name plus model rather than by name alone. The composite-key helper defined a few lines away in the same chunk already uses ` ${name}\x00${JSON.stringify(payload)} , and the assembler has the canonical model string in scope at the single Wvt` call site, so the value does not need to be threaded in from anywhere new. Keeping the plain section name as the resolver label preserves the existing telemetry and epoch check.
Impact
Any session that mixes models, which is the normal case once subagents run on a different model than the main loop. The subagent is told it is a different model than it is, is given the wrong knowledge cutoff, and inherits instructions gated to a model it is not.
Version
2.1.257 on Linux. Not checked on earlier builds.