Repository navigation
[Critical UX regression] multi-agent v2 spawn_agent hides model overrides and rejects the default call shape #32031
Description
Summary
On the multi-agent v2 surface (the default for gpt-5.6-sol / gpt-5.6-terra, and for any model when features.multi_agent_v2 is enabled), sub-agent model selection is effectively unusable: the default schema makes it undiscoverable, and the natural override call fails. The runtime fully supports the override — but agents on the default surface see no model property, conclude the capability does not exist, and tell users so. This is a severe UX regression from v1, where the spawn tool advertised up to 5 picker-visible models and fresh spawns with model overrides just worked.
Filing as an issue with a patch branch attached because PRs to this repo are staff-only.
What the user sees
User: "spawn a gpt-5.6-terra sub-agent for this"
Agent: "The current spawn_agent interface has no model selection argument, so I cannot spawn a sub-agent on gpt-5.6-terra."
The agent is wrong — SpawnAgentArgs parses and applies model / reasoning_effort regardless of schema visibility — but it has no way to know that, because the schema it sees does not contain those properties. Observed repeatedly with gpt-5.6-sol under ChatGPT auth, codex-cli 0.143.0 / Codex Desktop, main @ 1f0566d3f (2026-07-10).
Root cause: two compounding defaults
hide_spawn_agent_metadatadefaults totrue(core/src/config/mod.rs). The v2 spawn_agent schema stripsmodel,reasoning_effort,agent_type, andservice_tier, and drops the v1-style "Available model overrides" description listing up to 5 picker-visible models (hide_spawn_agent_metadata_options,core/src/tools/handlers/multi_agents_spec.rs).- Omitted
fork_turnsdefaults to a full-history fork, which rejects overrides (core/src/tools/handlers/multi_agents_v2/spawn.rs+reject_full_fork_spawn_overrides). So even when the model is told the arguments exist, the natural call — overrides without an explicitfork_turns— errors withFull-history forked agents inherit the parent agent type, model, and reasoning effort; .... The override only works withfork_turns: "none"or a partial fork, which nothing on the default surface teaches.
Each default is defensible alone; together they make a supported capability undiscoverable AND broken in its natural call shape. Users relying on the default surface can hit both walls before ever learning the explicit-fork workaround exists.
The config escape hatch does not work under ChatGPT auth
Setting [features.multi_agent_v2] hide_spawn_agent_metadata = false locally is not a workaround for ChatGPT-auth users: in our testing (ChatGPT auth, gpt-5.6-sol, 2026-07-10) the backend treats collaboration.spawn_agent as a reserved function and rejects every request whose declared schema deviates:
Invalid Value: 'tools'. Function 'collaboration.spawn_agent' is reserved for use by this model and must match the configured schema.
So for this configuration the hidden schema is the only accepted one, and the only working path is undocumented prompt knowledge. A client-side default flip therefore requires a coordinated update to the backend's reserved-function schema — which is exactly why this needs to be fixed here rather than worked around downstream.
Reproduction
codexwith a v2-surface model (e.g.gpt-5.6-sol, ChatGPT auth, all defaults).- Ask: "spawn a sub-agent on gpt-5.6-terra".
- Observe the agent either (a) claim model selection is unsupported, or (b) attempt
spawn_agent {model: "gpt-5.6-terra"}withoutfork_turnsand receive the full-history-fork rejection. - Optionally set
hide_spawn_agent_metadata = falseand observe the reserved-schema rejection above on every turn.
Proposed fix (patch branch attached)
Branch: https://github.com/lidge-jun/codex/tree/codex/spawn-agent-metadata-ux (single commit fde7de4d0; happy to iterate)
- Default
hide_spawn_agent_metadatatofalse— restore v1 parity: the schema advertises the override arguments and up to 5 picker-visible models. The slim schema stays available as an explicit opt-in. Note: this also surfaces the spawned agent'snicknamein results (SpawnAgentResult::WithNickname), and needs the coordinated backend schema update noted above for ChatGPT-auth configurations. - When
fork_turnsis truly omitted and an override (agent_type/model/reasoning_effort) is present, treat the spawn as fresh (fork_turns: "none") instead of erroring — unstated fork intent plus explicit override intent means a fresh specialist spawn, matching v1 semantics. Explicit input keeps its meaning:fork_turns: "all"(and blank strings) still keep the full-history default and reject overrides, preserving the inherit-everything contract.
Tests: overrides-with-omitted-fork_turns fresh-spawn behavior, explicit-all agent_type-only rejection, blank-fork_turns rejection, surfaced nickname expectations. cargo test -p codex-core --lib multi_agents: 89 passed / config::: 439 passed / integration spawn_agent filter: 7 passed. Pre-existing failure unrelated to this patch: multi_agent_v2_completion_ignores_dead_direct_parent stack-overflows on a clean checkout of main @ 1f0566d3f.
Why this deserves priority
This is a capability regression with active user-facing misinformation: the agent confidently tells users a shipped capability does not exist, and the failure mode (agent denial) means most users will never learn the capability is there at all. The fix is small, v1-parity-restoring, and covered by tests — the main coordination cost is the backend schema update, which only this repo's owners can drive.
Activity
github-actions commentedon Jul 10, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
lidge-jun commentedon Jul 10, 2026
Reviewed both candidates — they are related but this issue is not a pure duplicate of either. To make triage easy:
Overlap:
hide_spawn_agent_metadata = truedefault removingagent_type/model/reasoning_effort/service_tierfrom the v2 schema), and helpfully traces it to PR feat: default hide_spawn_agent_metadata to true #26114. This issue independently confirms that finding.collaboration.spawn_agent.What this issue adds that neither covers:
fork_turns— still fails, because omittedfork_turnsdefaults to a full-history fork andreject_full_fork_spawn_overridesrejects it. Fixing the schema visibility alone (GPT-5.6 Sol cannot specify subagent models, forcing all subagents to also be Sol instances #31814's ask) leaves this second wall in place: the model must also know to passfork_turns: "none", which nothing on the surface teaches.fork_turns+ override fall back to a fresh spawn (explicit"all"still rejects, preserving the inherit contract). 89 targetedmulti_agentstests pass, including new coverage for the fallback and blank-fork_turnsedge cases.Happy to consolidate into #31814 if maintainers prefer one thread — but please carry the
fork_turnscompounding default over if so, since restoring schema visibility alone does not make the natural call succeed.hoojunhao commentedon Jul 10, 2026
I can reproduce the visible-schema side of this on Codex Desktop / CLI 0.144.1 (macOS).
model_reasoning_effortconfigured.modelandmodel_reasoning_effort.spawn_agenttool exposed to this interactive thread accepts onlytask_name,message, andfork_turns. It exposes noagent_type,model, or reasoning-effort parameter.Expected: either expose a supported custom-agent selector and/or per-spawn
model/model_reasoning_effortfields, or document this surface's limitation and a supported routing mechanism.This matters for intentionally routing bounded sub-tasks to a faster/lower-cost model while keeping the parent on a stronger model.
I am intentionally not including local paths, account information, or full configuration output.
labib-rahman-zocdoc commentedon Jul 10, 2026
Confirming reproduction. This is breaking a lot of the guidance and training we've written for Codex usage in my organization.
Enforce bounded MultiAgent V2 nesting (#1)
Enforce bounded MultiAgent V2 nesting (#1)
Enforce bounded MultiAgent V2 nesting (#1)
Loong0x00 commentedon Jul 20, 2026
Strong +1. This should not require defining a static custom-agent preset for every model × reasoning-effort combination.
The parent agent should be able to pass ordinary string arguments for each individual spawn:
{ "task_name": "implement_small_change", "message": "...", "fork_turns": "none", "model": "gpt-5.6-terra", "reasoning_effort": "high" }That is a basic orchestration primitive: use a strong coordinator, cheaper/faster workers for bounded tasks, and stronger reviewers only where needed. Hiding these parameters and forcing every child to inherit the parent wastes usage and makes adaptive routing impossible.
Claude Code already supports this.
Please expose
modelandreasoning_effortin the stable model-visiblespawn_agentschema. If a requested value is unsupported, fail explicitly rather than silently inheriting the parent configuration.lidge-jun commentedon Jul 24, 2026
Confirming this is still current on
mainas of today.codex-rs/core/src/tools/handlers/multi_agents_spec.rswas last touched 2026-07-18 (#33932), so the logic below is what ships right now.Fresh file:line evidence (@
f201c30c5):multi_agents_spec.rs:116-119:core/src/tools/spec_plan.rs:819-822wiresexpose_spawn_agent_model_overridesstraight fromconfig.multi_agent_v2.expose_spawn_agent_model_overrides(defaultfalse). Nothing in the product turns it on, so every default v2 surface hides the capability.spec_plan.rs:869setsexpose_spawn_agent_model_overrides: truefor the v1 tool. This is the exact asymmetry behind the "regression from v1" report.core/src/tools/handlers/multi_agents_v2/spawn.rs(SpawnAgentArgs) parsesmodel,reasoning_effort, andservice_tierand applies them. The capability exists; only the advertisement is missing.additionalProperties: falseandrequired: ["task_name", "message"](multi_agents_spec.rs:137-141). So an agent that trusts the schema concludes "model selection does not exist" and tells the user so, and an agent that attempts the natural override anyway (model: "...", from v1 habit or explicit user instruction) risks a schema-validation rejection. Undiscoverable and punished for trying.Why this matters more than a normal feature gap: the tool schema is the model's only source of truth about its own capabilities. Hiding a supported property doesn't just obscure a feature — it manufactures false "I can't do that" answers, which is strictly worse UX than not having the feature.
Minimal fix proposal: align v2 with v1 — advertise
model/reasoning_effortby default (flip theDefaultforexpose_spawn_agent_model_overridestotrue, or drop the stripping entirely). The existingmulti_agent_v2.expose_spawn_agent_model_overridesconfig knob can stay as an opt-out for deployments that want to lock sub-agent models. Happy to prepare this as a patch branch on my fork if a maintainer confirms the direction (PRs here are staff-only).Gerry9000 commentedon Jul 29, 2026
Confirmed on Ubuntu with
codex-cli 0.145.0.The native
collaboration.spawn_agentschema available to the parent advertises explicit model overrides forgpt-5.6-solandgpt-5.6-terra, but omitsgpt-5.6-luna. Agents consequently report that Luna cannot be selected through native spawning.As a control, Luna works successfully through the same installed CLI:
So this still reproduces on 0.145.0 as a native subagent schema/model-catalog limitation, not a CLI-version inability to run Luna directly.
Gerry9000 commentedon Jul 29, 2026
Verified working workaround on Ubuntu with
codex-cli 0.145.0and ChatGPT authentication. The immediate rejection is caused by the bundled catalog marking Sol/Terra as MultiAgent V2 while Luna is marked V1;model_supports_multi_agent_backendtherefore filters Luna from a V2 parent.Create a full catalog override with only Luna changed to V2:
pbowyer commentedon Jul 30, 2026
@Gerry9000's catalog override worked for me, and I've fixed the formatting in their message so you can copy and paste:
Add to
~/.codex/config.toml:Caveat:
model_catalog_jsonreplaces the full bundled catalog, so this file should be refreshed when Codex updates and removed once the upstream catalog marks Luna V2.Enforce bounded MultiAgent V2 nesting (#1)
feat(subagent): optionally recover encrypted child task payloads