You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Regression in muli-agent spawning in 0.113.0 #14288
What terminal emulator and version are you using (if applicable)?
Ghostty
What issue are you seeing?
0.113.0 introduced a regression in multi-agent handing. Previously, if an agent's developer prompt contained instructions to spawn sub-agents, it would do so. Now what I see happening is that an "Orchestrater" agent is spawned of the correct type, when then spawns another agent of the same type, which then spawns the desired sub-agents.
I have a strong local root-cause candidate for this one, but I’d frame it narrowly.
My current read is that the issue is likely in forked sub-agent handoff rather than generic multi-agent planning.
What seems to be happening:
spawn_agent(..., fork_context=true) inherits parent rollout history into the child
the child also gets a synthetic handoff telling it to treat the next user message as its task
but the parent’s most recent live user directive can still remain in inherited history
if that parent directive is itself about delegation/orchestration, the child can reinterpret it as its own instruction and recurse
This also seems consistent with the older related report in #13491.
Locally, I patched the forked-spawn path to:
truncate inherited history before the parent’s last user message
preserve the parent spawn_agent function-call marker when needed
keep the synthetic fork handoff output
That gives the child completed background context without the parent’s active directive.
I added targeted regression coverage for:
unit-level forked spawn history shaping
rollout truncation before the last user message
integration coverage showing the child still receives earlier parent context, but not the current parent turn prompt
Those targeted codex-core tests passed locally.
I also ran a full workspace cargo test. It was not fully green on this machine, but the failures I hit were in unrelated EMFILE rollback-reconstruction tests and local seatbelt sandbox tests, not in the multi-agent fork path.
This is due to model behaviour. We will study this and see what's the best way to fix.
Truncating in the parent history might actually be sub-optimal...
Created a new log file for a slightly different behavior that I just observed where the top-level agent spawned the three specialized agents. Each of the specialized agent spawn three additional specialized agents, for a total of ten agents.
Model behavior can still affect whether the child chooses to delegate again.
The forked child history is also leaking a product-side instruction boundary.
spawn_agent(..., fork_context=true) snapshots parent rollout into the child
the child already receives its own task framing from the synthetic fork handoff and synthetic spawn_agent output
on clean upstream main, the second-generation fork test still fails at assert!(!body_contains(&grandchild_request, TURN_1_PROMPT)), so the grandchild request still contains the parent's live "spawn a child and continue" directive instead of only its own spawned task
in the targeted local tests, trimming inherited rollout before the newest surviving user-turn segment kept earlier completed context and spawn markers but removed the conflicting live delegation turn
that also removes the leaked parent TurnStarted scaffolding instead of cutting only at the raw user-message item
re-attaching the specific parent spawn_agent call and synthetic output keeps the fork handoff contract intact after trimming
the segment-based version still passes the same first-generation and second-generation fork tests locally
The leaked boundary is the inherited live delegation turn, not generic background context.
The strongest current fix shape is: drop the newest surviving user-turn segment from the forked rollout, then re-attach the specific parent spawn_agent call and synthetic output before handing control to the child.
Activity
github-actions commentedon Mar 11, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
SproutSeeds commentedon Mar 16, 2026
I have a strong local root-cause candidate for this one, but I’d frame it narrowly.
My current read is that the issue is likely in forked sub-agent handoff rather than generic multi-agent planning.
What seems to be happening:
spawn_agent(..., fork_context=true)inherits parent rollout history into the childThis also seems consistent with the older related report in
#13491.Locally, I patched the forked-spawn path to:
spawn_agentfunction-call marker when neededThat gives the child completed background context without the parent’s active directive.
I added targeted regression coverage for:
Those targeted
codex-coretests passed locally.I also ran a full workspace
cargo test. It was not fully green on this machine, but the failures I hit were in unrelatedEMFILErollback-reconstruction tests and local seatbelt sandbox tests, not in the multi-agent fork path.jif-oai commentedon Mar 16, 2026
This is due to model behaviour. We will study this and see what's the best way to fix.
Truncating in the parent history might actually be sub-optimal...
randall-8080 commentedon Mar 16, 2026
Created a new log file for a slightly different behavior that I just observed where the top-level agent spawned the three specialized agents. Each of the specialized agent spawn three additional specialized agents, for a total of ten agents.
Log: 019cf8a6-81a4-7a22-bf56-98dcc64c270e
SproutSeeds commentedon Mar 17, 2026
Model behavior can still affect whether the child chooses to delegate again.
The forked child history is also leaking a product-side instruction boundary.
spawn_agent(..., fork_context=true)snapshots parent rollout into the childspawn_agentoutputmain, the second-generation fork test still fails atassert!(!body_contains(&grandchild_request, TURN_1_PROMPT)), so the grandchild request still contains the parent's live"spawn a child and continue"directive instead of only its own spawned taskTurnStartedscaffolding instead of cutting only at the raw user-message itemspawn_agentcall and synthetic output keeps the fork handoff contract intact after trimmingThe leaked boundary is the inherited live delegation turn, not generic background context.
The strongest current fix shape is: drop the newest surviving user-turn segment from the forked rollout, then re-attach the specific parent
spawn_agentcall and synthetic output before handing control to the child.Patch I validated:
SproutSeeds@a26e5df
Full branch:
https://github.com/SproutSeeds/codex/tree/sprout/issue-14288-fork-turn-segment
fix(core): scope inherited history for forked subagents