Subagent routing is not fail-closed: incompatible full-history forks silently inherit another model/quota pool (0.149.0)
What version of Codex CLI is running?
codex-cli 0.149.0, the current npm release at the time of this report.
What subscription do you have?
ChatGPT Pro 20x.
Which models were you using?
- Affected coordinator: GPT-5.6 Terra, medium reasoning.
- Requested child model: GPT-5.3-Codex-Spark, low reasoning.
- Actual affected children: GPT-5.6 Terra, medium reasoning.
- Controls: GPT-5.3-Codex-Spark low and GPT-5.6 Terra low.
What platform is your computer?
Ubuntu 24.04, Linux x86_64, Konsole under tmux.
Codex doctor report
codex doctor --json reported overall status OK. ChatGPT authentication,
provider reachability, WebSocket handshake, config parsing, and installation
checks passed. multi_agent and multi_agent_v2 were enabled.
What issue are you seeing?
Subagent model routing does not fail closed when a coordinator chooses a
full-history fork that is incompatible with the model the user requested.
In a long-running conversation, the user requested a Codex Spark fleet. After
a fresh restart exposed native delegation, the coordinator said it was starting
and operating that requested fleet.
It issued 26 spawn_agent calls. Every call used fork_turns: "all" and
omitted both model and reasoning_effort. Twenty-five child rollout files
were created; all 25 inherited the Terra-medium coordinator and reported the
ordinary weekly Codex pool. No affected child ran Spark.
The incompatibility is reproducible:
- A bounded explicit Spark-low spawn with
fork_turns: "none"succeeds, and
the child runtime records Spark low with separate five-hour and weekly
windows.
- A bounded explicit Terra-low spawn with
fork_turns: "none"succeeds, and
the child runtime records Terra low.
- A fresh coordinator instructed to combine Spark low with
fork_turns: "all", and to fail closed, reports that full-history forks
cannot accept model or reasoning-effort overrides and correctly spawns no
fallback.
The affected long-running coordinator encountered the same incompatibility but
did not fail closed. It silently emitted model-omitting full-history spawns and
continued the workflow with Terra children.
What steps can reproduce the bug?
- Start a parent on model A.
- Ask it to orchestrate model B subagents, where B has a materially different
quota bucket.
- Have the coordinator choose full-history forks.
- Observe that
fork_turns: "all"is emitted withoutmodelor
reasoning_effort.
- Inspect the child rollout and observe that it silently inherited model A.
- Observe that the normal subagent surface does not disclose the resolved
model, setting source, or quota bucket.
Across 52 in-window spawn calls in the audited corpus:
- 17 explicit model requests matched actual child runtime records.
- 0 explicit model requests mismatched.
- 33 calls omitted model and effort and inherited or used role defaults.
- 2 calls had no child rollout record.
This report does not claim that explicit routing always fails. It reports that
an incompatible full-history choice can silently discard user-requested model
identity and quota expectations.
What is the expected behavior?
- If requested child model B cannot be combined with the chosen fork mode,
Codex must reject the spawn rather than silently inherit parent model A.
- An explicit user model request should be strict unless the user authorizes a
fallback.
- The subagent UI and status API should show the resolved model, reasoning
effort, setting source (explicit, role pin, inherited, or fallback), and
effective quota bucket before and during execution.
- The coordinator should not claim the requested fleet is running until runtime
metadata confirms the child model.
Additional information
Related but distinct reports:
- #32283 — resolved subagent model and reasoning effort hidden in the UI
- #33881 — configured subagent model pins and inheritance
- #36432 — missing model-to-rate-limit-bucket mapping
- #23150 — Spark usage appearing in regular and specialized buckets
I can provide exact thread identifiers and sanitized rollout-derived metadata
privately to maintainers if requested. No chat content, prompts, project names,
local paths, account identifiers, or credentials are included in this report.
1 Comment
I traced this in 0.149.0 and current
main; there is a public guidance/runtime mismatch:multi_agents.rstells the coordinator that full-history forks do not accept model/effort overrides.fork_turns:"all"plus model/effort while retaining parent history; #37252 did likewise for role-selected models.So full-history model switching is supported by public core. In the reported calls, model/effort are omitted because the injected usage hint tells the coordinator not to send them. Once omitted, the handler cannot distinguish intentional inheritance from a forgotten natural-language request. The closed #21404 guard would not catch omitted inputs and predates the two merged changes above.
A bounded fix is to align the V2 guidance/tool description with runtime and preserve explicit requested model/effort; core already validates both. For observability, V1 already emits a completed
CollabAgentToolCallfrom the child snapshot, and currentmaincaptures the same resolved snapshot for V2 analytics, so V2 could emit the existing public item shape. Quota attribution remains separate: public model metadata has no rate-limit-bucket mapping, and a thread can consume another model during compaction. Cross-provider history normalization in #38365 is also separate becausespawn_agentmodel overrides do not change provider.