[Bug] Subagent pinned to claude-fable-5 deterministically swaps to claude-opus-5 after exactly 3 turns

Status Open
Reported on v2.1.221
Maintainer reply None cached
Activity 0 comments · opened Aug 6, 2026

Bug Description

# Bug report v3 — deterministic mid-run model substitution: pinned claude-fable-5 subagents swap to claude-opus-5 after exactly 3 calls Observed: 2026-08-05 and 2026-08-06 (7 consecutive runs) · Claude Code: 2.1.221 at last verification (2026-08-04; current session's version not re-checked) · Type: model routing / serving-side substitution · Supersedes/extends: the v2 report + addenda of 2026-08-04 (same environment) ## Summary A subagent whose definition pins model: claude-fable-5 is served claude-fable-5 for exactly its first 3 assistant turns, then silently served claude-opus-5 for every remaining turn of the same run. This 3-then-swap signature has now occurred in 7 of 7 consecutive launches of the same agent definition, across two days, two separate sessions, and task lengths from ~28 to ~171 API calls. The swap point's regularity is the new information: earlier observations (v2) included launch-time substitution and mid-run swaps at irregular points (after 13 calls; after 3); the behavior has now stabilized into a deterministic boundary at call 3→4. ## Configuration under test (unchanged across all 7 runs) - Subagent frontmatter: model: claude-fable-5; tools: Read, Edit, Write, Grep, Glob, Bash (deliberately no Skill, no Agent — the restricted shape that previously passed a 5/5 all-fable acceptance on 2026-08-04 ~16:56). - Launched via the Agent/Task tool with no model parameter (frontmatter pin governs); CLAUDE_CODE_SUBAGENT_MODEL unset/inherit. - Main conversation loop: unaffected in all observations. ## The measurement (serving stamps — the API response's own model field per assistant turn, tallied per child transcript) grep -oh '"model":"claude-[^"]*"' <child_transcript>.jsonl | sort | uniq -c | run | date | served claude-fable-5 | served claude-opus-5 | |---|---|---|---| | 1 | 2026-08-05 ~10:45 | 3 | 64 | | 2 | 2026-08-05 ~11:50 | 3 | 122 | | 3 | 2026-08-05 ~12:55 | 3 | 161 | | 4 | 2026-08-05 ~14:40 | 3 | 168 | | 5 | 2026-08-05 ~15:20 | 3 | 90 | | 6 | 2026-08-05 ~16:25 | 3 | 148 | | 7 | 2026-08-06 ~11:16 (checked mid-run) | 3 | 25+ (still running at check) | Every run: the first 3 assistant turns are fable, all subsequent turns are opus-5, with no error, no warning, and no change in any request-side parameter across the boundary (v2's differential audit had already eliminated the visible request dimensions on an earlier instance of the swap). ## Contrast data from the same sessions - Children of other agent types requesting sonnet in the same sessions: served claude-sonnet-5 faithfully every time (7+ runs, 34–168 calls each, zero substitutions). - One harness-built "Plan" subagent (a different, restricted tool set) on 2026-08-05 ~10:10 was served claude-fable-5 for 47/47 turns — the only fully-faithful fable run in the window, within the hour before run 1 above began its 3-then-swap. - Explicitly-requested claude-opus-5 (a pinned supervised executor) and the main loop's own model: always served as requested. ## What v2 established that still holds - The substitution is serving-side: launch-time resolution is correct (resolvedModel: claude-fable-5), the pin is honored at request level, and the swap is invisible except in per-turn serving stamps. Child self-report is unreliable for detection. - Request-side dimensions (arguments, effort, session, thinking, size to ~87k, timing) were eliminated by a differential audit; granting the Skill tool was isolated as a sufficient-but-not-necessary trigger; two independent projects reproduced 0/15 faithful on the identical definition. - Rates were session/time-conditioned (100% faithful in one window, 0% in others on unchanged files). ## What is NEW in v3 1. The swap point is deterministic: exactly 3 fable turns, then opus-5, in 7/7 consecutive runs of the unchanged definition — stable across days, sessions, and task sizes. Previously the swap point varied (13-then-74 on one agent; 3-then-24 once). 2. The regularity suggests a systematic mechanism at the serving layer rather than random failover. Hypotheses (unverified, offered for triage): a router re-evaluation after N turns; a context-size threshold crossed once the first few (typically small) tool results give way to larger ones; a serving-affinity or cache TTL expiring after the initial calls — or something else on the serving side we cannot observe. 3. Practical consequence: a "first-turns spot check" of a run now reads as faithful while ~95% of the run executes on the wrong model. Any client-side verification must tally every turn. ## Reproduction 1. Define a subagent pinned model: claude-fable-5, tools Read, Edit, Write, Grep, Glob, Bash, no Skill/Agent. 2. Launch paramless with a multi-step task (≥10 tool calls). 3. Tally serving stamps per the command above.…
Note: Content was truncated.

View original on GitHub ↗