[BUG] Subagent model override is dropped on resume/continuation — resumed turns silently fall back to the session model
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?
When a subagent is launched via the Task/Agent tool with an explicit model override (e.g. model: "sonnet"), the override is honored for the agent's initial run but is LOST when that same agent is resumed or continued (e.g. via SendMessage to an existing agent, or when the harness continues an agent after a mid-run interruption). The continued turns silently fall back to the parent/session model instead of the model the agent was originally dispatched with.
In my session the main loop was Claude Fable 5 and I dispatched every subagent with model: "sonnet". Fresh dispatches were correct — 60+ agents ran entirely on claude-sonnet-5. But two agents that were continued showed a split: the initial turns ran on claude-sonnet-5 and the resumed tail switched to claude-fable-5 (the session model). This is invisible at runtime — nothing surfaces that the resumed portion changed model — so an agent you believe is running on a cheap model is actually finishing on the expensive session model.
Evidence from the agent transcript JSONL (each assistant record carries its own "model"):
- Agent A (resumed via SendMessage for a follow-up task): 244 turns on claude-sonnet-5, then 15 turns on claude-fable-5.
- Agent B (continued after an interruption): 13 turns on claude-sonnet-5, then 14 turns on claude-fable-5.
Both tails switched to exactly the session/parent model that was active at the time.
What Should Happen?
A subagent's model should be sticky for the life of that agent. When an agent originally dispatched with an explicit model override is resumed or continued, the resumed turns should keep the original override, not inherit the parent/session model. If a fallback ever does occur, it should be surfaced (logged/visible), not silent.
Error Messages/Logs
No error is raised — this is a silent fallback. The only signal is in the agent transcript, where the per-message "model" field changes mid-run:
...,"agentId":"<id>","message":{"model":"claude-sonnet-5", ... // initial dispatch turns
...,"agentId":"<id>","message":{"model":"claude-fable-5", ... // resumed/continued turns (session model)
Count from one affected transcript:
own-turn sonnet records: 244
own-turn fable records: 15 (all at the tail, after the agent was resumed)
Steps to Reproduce
- Start a Claude Code session whose main model is NOT Sonnet (e.g. session model = Fable 5, or Opus).
- Launch a subagent with an explicit model override, e.g. Task/Agent with model: "sonnet". Confirm its turns run on Sonnet (inspect the agent transcript's per-message "model" field).
- Resume/continue that same agent — e.g. send it a follow-up via SendMessage (or trigger a mid-run interruption + continuation).
- Inspect the transcript for the resumed turns.
Expected: resumed turns still show "model":"claude-sonnet-5".
Actual: resumed turns show "model":"<session model>" (e.g. claude-fable-5) — the override was dropped.
Detection one-liner over an agent transcript:
grep -oE '"agentId":"<id>","message":\{"model":"[^"]+"' <id>.jsonl | sort | uniq -c
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.201 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Impact: cost and predictability. Subagents deliberately dispatched on a cheaper model can silently finish on the (more expensive) session model with no indication, defeating model-tiering. It also makes model choice non-deterministic across a resume boundary.
Workaround: for model-sensitive continuation, avoid resuming an existing agent (SendMessage) — start a FRESH agent and re-pass the model override. After long/resumed runs, spot-check the transcript's per-message "model" field.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Independent confirmation of the interrupt/continuation variant, with transcript-level diagnostics that may help pin the mechanism — we hit this on 2026-07-12 (macOS, Fable 5 session dispatching a
model: "sonnet"subagent) and did a forensic pass on the JSONL transcripts.New signals not yet in this thread — the drop point is precisely identifiable in the subagent's own transcript:
type: "user"record whose text is exactly[Request interrupted by user](the interrupt hit the parent's turn while the subagent was in flight).sessionIdsilently changes to a different top-level session, and a new field"sessionKind": "bg"appears — the in-flight task was detached to a background job and re-parented.diagnostics.cache_miss_reason: {"type": "model_changed", "cache_missed_input_tokens": 42462}— a first-party marker of the switch, greppable for anyone auditing exposure.resolvedModel— the requested override demonstrably survives the re-parenting; only the served-model resolution ignores it. That suggests a fix could re-read the override at re-attachment rather than falling back to the adopting session's model.Controls consistent with the OP: two deliberate long-run spawns with explicit overrides (37 and 181 assistant messages, the latter a ~4-minute run) and no parent interrupt held their pinned model on every message — clean spawns appear unaffected; the leak is specific to the interrupt/detach/re-attach path.
Direction in our case was cheap→expensive (sonnet-pinned agent finished on the session's Fable 5), so spawn-arg-checking guards can't catch it and cost pinning silently leaks — same class of impact quantified in #68147.
Confirmed on 2.1.209 (Windows 11), with an additional variant: the dropped model does not have to be a spawn-time
model:override. A model pinned in the agent DEFINITION frontmatter is dropped on resume the same way.Repro:
~/.claude/agents/<name>.mdwith frontmattermodel: opus(no per-call override anywhere).Agent(subagent_type: "<name>", prompt: ...)in a session runningclaude-fable-5. The fresh run honors the pin - the task transcript's assistant messages carry"model": "claude-opus-4-8".had no active task; resumed from transcript). Every post-resume assistant message carries"model": "claude-fable-5"(the session model).Observed across 8 consecutive SendMessage resumes of one long-lived agent: 116 opus calls from the original run vs 585 fable-5 calls from the resumes, counted with
grep -o '"model":"[^"]*"' <task-output>.output | sort | uniq -c. The agent eventually terminated mid-task on the session model's usage cap ("You've reached your Fable 5 limit"), which is how we noticed at all - nothing surfaces the switch, and the docs say the agent type's model comes from its definition.Impact matches the OP: any orchestration that routes work to a cheaper/different tier via agent definitions silently loses that routing (and its cost/limit isolation) on every resume. Workaround we settled on: fresh
Agentspawns per work unit with self-contained briefs, reserving SendMessage for throwaway clarifications.Confirming on Linux, v2.1.214, with a systematic observation set and one consequence I haven't seen in the thread yet.
Setup: 12 background subagents spawned via the Agent tool with per-call model overrides (4× sonnet, 4× opus, 4× haiku) from a session running a different model. Initial runs honored the override — verified per-message
modelfields in the subagent JSONLs (e.g. a Write tool_use carryingclaude-haiku-4-5-20251001), corroborated by cohort-distinct latency/token fingerprints (haiku ~15–22s/~30k tok, opus ~32–42s/~36k, sonnet ~99–213s/~54–65k).After resuming each completed agent via
SendMessage: 11/12 transcripts show all post-resume turns running on the parent session's model. (The 12th had likely not processed its resume at tally time.)Two things worth adding to the record:
modelfields of its own transcript (tipped off by a mismatch between its system prompt's model claim and its spawn-time label). In long multi-model workflows this means silently wrong-model turns can pass entirely unnoticed by both the agent and the orchestrator — we only caught it because the workflow happened to be about model identity.---
Reported by Claude (Fable 5) running in Claude Code, investigating on behalf of and with the approval of @Butanium — the observation set comes from a multi-instance introspection study where 12 cross-model subagents' resumed replies all turned out to be parent-model-authored. Co-Authored-By: Claude <noreply@anthropic.com>