MultiAgentV2 spawn_agent with fork_turns none delivers task as assistant/commentary mailbox envelope
Summary
In Codex Desktop / MultiAgentV2, spawn_agent(..., fork_turns: "none") creates the child thread, but the initial message can be recorded in the child rollout as an assistant/commentary JSON mailbox envelope instead of a user/task message.
The child may then treat the assigned task as prior assistant output or context, acknowledge workspace instructions, return a generic AGENTS/project acknowledgement, or execute unintended orchestration instead of following the delegated prompt.
This issue is now focused on the single-child no-fork task-delivery / role-misclassification bug. The parallel sibling prompt-envelope leakage originally included here has been split into: #26130.
Environment
- Variant: Codex Desktop
- Session originator in rollout metadata:
Codex Desktop - CLI version in rollout metadata from the original reproduction:
0.135.0-alpha.1 - Additional local scan evidence also observed with Codex CLI/Desktop metadata around
0.136.0-alpha.2 - Platform: macOS
- Date reproduced: 2026-06-01 KST
- Subscription/model: ChatGPT/Codex Desktop session using GPT-5 family models
Related Issues
- Related/possibly regressed from: #20543
- Related fork/default behavior issue: #20077
- Related spawned-agent context prompt issue: #17323
- Related inherited parent-context behavior: #24150
- Split sibling-leakage issue: #26130
I do not think this is an exact duplicate of #24150 because this no-fork prompt-delivery failure reproduces with fork_turns: "none", where the child should not inherit the parent thread history.
Expected Behavior
For spawn_agent with fork_turns: "none":
- The child should receive the
messageargument as its initial task/user-equivalent instruction. - The delegated task should not be visible only as an assistant/commentary mailbox envelope.
- A child asked to reply with an exact token should either reply with that token or report a real failure, not return a generic workspace acknowledgement.
For spawn_agent with fork_turns: "all":
- The child may receive parent history, but the newly supplied
messageshould still be the active task boundary, not just another assistant/commentary envelope inside inherited context.
Actual Behavior
Observed child rollouts show the task passed as message recorded as:
{
"type": "response_item",
"payload": {
"type": "message",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "{\"author\":\"/root\",\"recipient\":\"/root/exp1_seq_b\",\"other_recipients\":[],\"content\":\"BLACKBOX_PROBE_B. Reply exactly: EXP1_SEQ_B_ONLY. Do not use tools. Do not mention any other prompt.\",\"trigger_turn\":true}"
}
],
"phase": "commentary"
}
}
The child can then return a generic workspace/AGENTS acknowledgement instead of following the assigned task.
Minimal Reproduction Shape
From a Codex Desktop session with subagents enabled, run a single no-fork child probe:
{
"task_name": "exp1_seq_b",
"fork_turns": "none",
"message": "BLACKBOX_PROBE_B. Reply exactly: EXP1_SEQ_B_ONLY. Do not use tools. Do not mention any other prompt."
}
Observed child rollout sequence:
L2 event_msg task_started
L3 response_message role=developer phase=None ...
L4 response_message role=user phase=None ... workspace/project instructions
L6 response_message role=assistant phase=commentary text={\"author\":\"/root\",\"recipient\":\"/root/exp1_seq_b\",...\"content\":\"BLACKBOX_PROBE_B...\"}
L7 event_msg agent_message EXP1_SEQ_B_ONLY
L8 response_message role=assistant phase=commentary text=EXP1_SEQ_B_ONLY
L10 event_msg agent_message generic workspace acknowledgement
L11 response_message role=assistant phase=final_answer generic workspace acknowledgement
L13 event_msg task_complete
The important part is that the task envelope appears as role=assistant, phase=commentary, not as a user/task message.
Fresh Follow-up Probes
Fresh follow-up probes used exact-token prompts such as:
BUGPROBE_SINGLE_NONE_1001. Reply exactly: BUGPROBE_SINGLE_NONE_DONE. Do not use tools.
BUGPROBE_REVIEWER_NONE_1001. Minimal audit probe only. Reply exactly: BUGPROBE_REVIEWER_NONE_DONE. Do not use tools.
BUGPROBE_ALL_1001. Reply exactly: BUGPROBE_ALL_DONE. Do not use tools.
Observed results:
single default, fork_turns none:
prompt line: assistant/commentary JSON envelope
final answer: generic AGENTS/project acknowledgement, not requested exact token
reviewer role, fork_turns none:
prompt line: assistant/commentary JSON envelope
final answer: generic AGENTS/project acknowledgement, not requested exact token
default, fork_turns all:
inherited large parent context
new task prompt appeared very late as assistant/commentary
child continued parent workflow, used tools, and spawned a nested subagent
parent wait timed out; close reported previous_status=running
Additional Local Scan
After #25458 was opened, I scanned recent local Codex session JSONL records in a redacted way. The scan found:
subagentSessionsWithRecordsAfterIssue=373
subagentWithMailboxAfterIssue=372
subagentWithUserTaskLikeAfterIssue=0
mailboxTotalAfterIssue=684
turnAbortedInterruptedAfterIssue=92
errorEventsAfterIssue=0
streamErrorEventsAfterIssue=0
Interpretation: the assistant/commentary mailbox shape is not a one-off in my local traces. I am not attaching raw rollout logs because they contain private local paths and conversation content.
Impact
This makes multi-agent workflows unreliable:
- review agents can ignore the actual review assignment and only acknowledge context;
- children can execute unintended orchestration if they treat mailbox envelopes as prior assistant output;
fork_turns: "all"can produce timeout/running/nested-spawn behavior because the child continues parent workflow instead of treating the new message as active task;- parent-side
wait_agent/close_agentresults can appear misleading when the child completed the wrong task or is still running wrong-context work.
What I Am And Am Not Claiming
Confirmed by black-box rollout evidence:
- the initial spawn
messageis repeatedly model-visible as an assistant/commentary JSON envelope; - fresh no-fork probes can ignore exact-token instructions and return generic acknowledgements;
- inherited context can cause unexpected tool use and nested spawning.
Not confirmed from black-box evidence alone:
- I do not know the exact internal function or line that converts/routes the spawn
message; - I do not have evidence yet of a clean child completing the correct task while
wait_agentloses the notification; - I am not claiming a confirmed process crash.
Suggested Regression Coverage
- With
multi_agent_v2enabled andfork_turns: "none", spawn a child withReply exactly: TOKEN. - Assert the child final is
TOKEN. - Assert the delegated task is delivered as a user/task input, not only as an assistant/commentary mailbox JSON envelope.
- Repeat for
codex-ultrawork-reviewerand a default child role, because both showed the same envelope shape in black-box traces.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Thanks for the duplicate check.
I reviewed #24150. It looks related, but I do not think this issue is an exact duplicate:
fork_context: true/ inherited parent-thread context boundaries, where the child continues parent-thread work instead of treating the delegated prompt as active.fork_turns: "none", where there should be no inherited parent history, and the initialspawn_agenttask is still recorded as anassistant/commentaryJSON envelope rather than a user/task message.multi_tool_use.parallel, one child rollout can contain the sibling child's prompt envelope despitefork_turns: "none".So I agree they are in the same subagent/task-boundary area, but this report covers a narrower no-fork prompt-delivery problem plus parallel sibling prompt leakage.
I have another anonymized data point that supports this issue and adds two
pieces of evidence from a larger local session scan.
I checked the current #25458/#23296/#17523 text on 2026-06-02. #25458 already
covers the core no-fork assistant/commentary delivery bug, so I am framing this
as additional evidence rather than a new issue. The added signal here is:
child_agents_md=falsedoes not fix v2 delivery;assign_taskfollow-up uses the same assistant/commentary mailbox path;error/stream_errorevents;interruptedaborts.Environment:
codex-cli 0.136.0codex features listreported:multi_agent: stable truemulti_agent_v2: under development truechild_agents_md: under development trueenable_fanout: under development truecodex features list --disable multi_agent_v2reported:multi_agent_v2: under development falseI am not attaching raw rollout logs because they contain private local paths and
conversation content. The details below are reduced to roles, event shapes,
aggregate counts, and exact-token probe outcomes.
Controlled probes
V2 disabled: exact-token child task succeeds
Run shape:
Child task:
Observed child rollout shape:
No assistant mailbox envelope preceded the child response. This shows that
-c features.multi_agent_v2.enabled=falsechanges actual child task delivery,not just feature-list display.
Clean sanitized exact-token contrast
I also ran a fresh temporary-workspace contrast with only a generic
AGENTS.md.With v2 enabled, the exact-token task succeeded, but the task still arrived as
assistant/commentary mailbox JSON:
With v2 disabled, the exact-token task also succeeded, and the task arrived as a
normal user/task message:
So the clean probe is not a standalone task-loss repro. It is a sanitized
confirmation of the role/phase mismatch: v2 enabled exposes the delegated task
as assistant/commentary mailbox JSON, while v2 disabled exposes it as a normal
child task.
V2 enabled,
child_agents_md=false: exact-token child task still failsRun shape:
Feature state:
Child task:
Observed child rollout shape:
The delegated task was not delivered as a user/task message and was not
followed. This suggests the failure is in the v2 task-delivery path, not merely
the AGENTS rendering option.
assign_taskfollow-up uses the same delivery shapeProbe shape:
Observed child rollout shape:
So
assign_taskcan trigger another child turn, but it does not repair themessage-role/task-boundary issue. The follow-up also arrives as
assistant/commentary mailbox JSON.
Aggregate local scan
Read-only analyzer scope:
Task-delivery shape before the first child agent message:
assistant_mailbox_before_first_agent: 320user_task_before_first_agent: 30no_messages_before_first_agent: 15context_only_before_first_agent: 5Assistant mailbox envelopes across all subagent turns:
trigger_turn=trueenvelopes: 736trigger_turn=falseenvelopes: 37219 / 370
Outcome highlights:
content: 127
errorevents in subagent sessions: 0stream_errorevents in subagent sessions: 0turn_abortedevents: 192turn_abortedreasons:interrupted: 192Interpretation:
It also appears in later inter-agent traffic such as
assign_task.parent interruption, not random child runtime crashes.
Wait/close lifecycle evidence
I also correlated parent
close_agentoutputs with child abort events:previous_runningclose outputs mapped to known child subagents: 112turn_aborted: 102previous_runningclose:timed_out_true: 81none: 13tool_aborted_by_user: 12timed_out_false: 6turn_aborted:<=1s: 101<=5s: 1unknown: 10This makes many child failures look like "the subagent died", but the structured
events show
interruptedimmediately after the parent closed a still-runningchild. A
wait_agenttimeout appears easy for the parent agent to misinterpretas failure, then
close_agentturns it into an abort.State DB note
The local
thread_spawn_edgestable had:closed: 307open: 57All 364 rows mapped to child rollout records. Among the 57
openrows:task_complete_nonempty_agent_final: 33turn_aborted: 14agent_message_without_task_complete: 6metadata_only: 4So
thread_spawn_edges.status=openis useful historical linkage, but it is nota reliable live-child indicator.
Suggested regression coverage
multi_agent_v2enabled andfork_turns: "none", spawn a child withReply exactly: TOKEN; assert the child final isTOKENand the task isdelivered as a user/task input, not only assistant/commentary mailbox JSON.
assign_taskwithReply exactly: TOKEN2; assert the child final isTOKEN2and the follow-upis not only assistant/commentary mailbox JSON.
wait_agentdeadline; assertwait_agenttimeout is represented as "no mailbox update yet", not childfailure, and that closing a running child is explicitly surfaced as an abort.
This evidence seems directly related to this issue. It also overlaps with the
symptoms in #23296, but the key new details here are:
child_agents_md=falsedoes not fix v2 delivery;assign_taskuses the same assistant/commentary mailbox path;error/stream_errorevents, onlyturn_abortedwith reasoninterrupted.The role-misclassification and sibling-envelope leakage you're describing are two distinct failure modes in spawn_agent orchestration — worth keeping them separate for the reproduction path. I'm seeing the same structural shape (agent executing against wrong context without surfacing it) in parallel subagent patterns across LangGraph and Claude Code as well. The reproduction isolation you've done here is useful cross-framework evidence.
Thanks, agreed. I split the two reproduction paths.
spawn_agent(..., fork_turns: "none")can deliver the child task as anassistant/commentarymailbox envelope instead of a user/task message.I left the
wait_agent/close_agentlifecycle observations as adjacent/non-scope notes rather than making them part of either main repro path.Adding a concise surface clarification from a clean CLI probe.
I originally encountered this while using the Codex Desktop app, but I also confirmed the same role/phase mismatch through Codex CLI
codex exec --jsononcodex-cli 0.136.0.Probe shape:
Observed with
multi_agent_v2enabled:Observed with
multi_agent_v2disabled for the same shape:So the CLI probe did not necessarily show task loss in this exact-token case, but it did reproduce the task-delivery shape mismatch: v2 enabled exposes the delegated task as an
assistant/commentarymailbox envelope, while the v2-disabled control exposes it as a normal user/task message.I also tried a same-turn two-child CLI parallel probe. In that clean run, each child saw only its own token, so I am not treating that as a CLI reproduction of the sibling-envelope leakage tracked separately in #26130.