Subagents can shut down without delivering results; fork_turns none scouts acted as orchestrators
Summary
In Codex Desktop / MultiAgentV2, a parent thread spawned three read-only scout subagents with fork_turns: "none". The parent never received a final answer or mailbox result from any child. Repeated wait_agent calls timed out on schedule; list_agents later showed the children as shutdown; close_agent then returned thread <id> not found.
Local child rollout logs show the children were not merely idle. Despite self-contained read-only scout prompts, they appear to have acted like orchestration agents: they called wait_agent, attempted close_agent on sibling scouts, emitted commentary about other scouts not returning, and then their turns were interrupted/aborted. None delivered the requested scout findings to the parent.
This makes subagents unreliable for long planning/review/scout workflows: the parent cannot distinguish "still running," "shutdown without result," "lost mailbox result," "thread not found," or "child misinterpreted inherited orchestration context."
Environment
- Variant: Codex Desktop / app-side multi-agent tools
- CLI visible locally:
codex-cli 0.137.0 - Platform: macOS 26.6, Darwin 25.6.0 arm64
- Account/subscription: ChatGPT Pro
- Parent rollout/session:
/Users/jstar/.codex/sessions/2026/06/06/rollout-2026-06-06T13-43-41-019e9ead-5b80-7e40-8f53-ed9e915b86a4.jsonl- session id
019e9ead-5b80-7e40-8f53-ed9e915b86a4 - Child rollout/session ids:
- runtime/jobs scout:
019e9eb0-2d48-7dc3-93c8-ba9241c99566 - frontend workflows scout:
019e9eb0-2ef6-72e3-a2b4-34eb785fdfd8 - docs/contracts scout:
019e9eb0-30d3-7bb3-97d4-6cd2a34845ac
Reproduction shape
This was observed during a repo planning task where the parent tried to fan out read-only exploration scouts.
- In a parent Codex Desktop thread, first attempt to spawn multiple scouts with
agent_typeplus a full-history fork. - Observe spawn validation error:
Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without a full-history fork.
- Retry with self-contained prompts and
fork_turns: "none":
scout_runtime_jobs,agent_type: "explorer"scout_frontend_workflows,agent_type: "explorer"scout_docs_contracts,agent_type: "explorer"
- Attempt a fourth scout. It fails with:
collab spawn failed: agent thread limit reached
- Parent waits repeatedly:
wait_agent({"timeout_ms":30000})-> timed outwait_agent({"timeout_ms":60000})-> timed outwait_agent({"timeout_ms":90000})-> timed outwait_agent({"timeout_ms":180000})-> timed out
- Parent checks agents:
- Early
list_agentsshowed the three scouts asrunning. - Later
list_agentsshowed the three scouts asshutdown. - No final answer/mailbox payload had arrived in the parent.
- Parent tries to close them and gets:
collab tool failed: thread 019e9eb0-2d48-7dc3-93c8-ba9241c99566 not foundcollab tool failed: thread 019e9eb0-2ef6-72e3-a2b4-34eb785fdfd8 not foundcollab tool failed: thread 019e9eb0-30d3-7bb3-97d4-6cd2a34845ac not found
Evidence from parent rollout
From parent rollout /Users/jstar/.codex/sessions/2026/06/06/rollout-2026-06-06T13-43-41-019e9ead-5b80-7e40-8f53-ed9e915b86a4.jsonl:
- Lines 26-29: first spawn attempts with
agent_type+fork_turns: "all"; all returned the full-history fork validation error. - Lines 38-45: retry with
fork_turns: "none"; three scouts spawned successfully and the fourth returnedagent thread limit reached. - Lines 262-263:
wait_agent30s timeout. - Lines 286-287:
wait_agent60s timeout. - Lines 292-293:
wait_agent90s timeout. - Lines 298-299:
wait_agent180s timeout. - Lines 268-269:
list_agentsshowed the three scouts asrunning. - Lines 304-309:
close_agentreturnedthread <id> not foundfor all three child ids. - Lines 314-315:
list_agentsshowed the three scouts asshutdown, still without any parent-delivered result payload.
Evidence from child rollouts
The child rollouts suggest this was not just slow/empty execution. The children appear to have drifted into orchestrator behavior and then aborted/interrupted.
- Docs/contracts scout, child session
019e9eb0-30d3-7bb3-97d4-6cd2a34845ac: - called
wait_agent({"timeout_ms":30000}), timed out - emitted commentary about scout threads still running
- attempted
close_agenton sibling scouts - close outputs reported
aborted by user after 0.1s - turn ended with
reason: "interrupted", duration about 279s - Frontend workflows scout, child session
019e9eb0-2ef6-72e3-a2b4-34eb785fdfd8: - called
wait_agent({"timeout_ms":60000}), timed out - emitted commentary that scout agents did not return
- attempted to close sibling/current scouts
- one close output reported
thread ... not found; another wasaborted by user after 0.1s - turn ended with
reason: "interrupted", duration about 326s - Runtime/jobs scout, child session
019e9eb0-2d48-7dc3-93c8-ba9241c99566: - called
wait_agent({"timeout_ms":10000}), timed out - emitted commentary that the frontend/doc scouts had shut down
- attempted
close_agenton itself - close output reported
aborted by user after 0.1s - turn ended with
reason: "interrupted", duration about 375s
Expected behavior
- A child spawned with
fork_turns: "none"and a self-contained read-only prompt should treat that prompt as the active task and should not start coordinating sibling agents unless explicitly instructed. - If a child shuts down, is interrupted, or aborts before producing a normal final answer, the parent should receive a structured terminal event through
wait_agent/mailbox. wait_agent,list_agents, andclose_agentshould agree on lifecycle state or return a structured explanation of the mismatch.thread <id> not foundshould not be the only close/readback signal for a thread that was previously spawned and visible throughlist_agents.- Thread capacity should be discoverable before spawn, or
spawn_agentshould return enough status onagent thread limit reachedto recover cleanly.
Actual behavior
- The parent received no usable scout content and no child final-answer payload.
wait_agentonly returned timeouts, even though child turns later ended/interrupted.list_agentstransitioned fromrunningtoshutdown, but the parent still received no terminal child result.close_agentreturnedthread <id> not foundfor each child.- Child rollouts show children calling orchestration tools (
wait_agent,close_agent) instead of simply completing their assigned scout prompts.
Related issues checked
I did not find an exact duplicate for this combined failure mode: child shutdown/no parent-delivered final result + not found cleanup/readback + fork_turns: "none" scouts acting as orchestrators.
Adjacent issues:
- #26728 -
Subagent completion result can be lost after parent thread compaction - Closest on lost child completion, but in this case no explicit parent compaction was observed during the wait cycle, and the child logs show interruption/orchestration drift rather than a normal completed child result being hidden after compaction.
- #24951 -
multi_agent wait_agent/spawn_agent can block for ~7.5h; wait_agent timeout_ms not enforced during runtime stall - Related to wait/spawn control-plane reliability. Here,
wait_agentdid return on timeout; the problem is missing terminal/result delivery and ambiguous lifecycle state. - #25426 -
close_agent can hang forever after marking a subagent closed if the child thread never terminates - Related lifecycle/close problem. Here, close did not hang; it returned
thread <id> not foundafter the parent had seen the children as spawned/listed. - #23479 -
Main agent needs subagent capacity/status preflight before spawn_agent attempts - Related to the fourth scout failing with
agent thread limit reachedand no clear preflight/capacity status. - #23930 -
Codex app subagent cards can remain stuck/visible after close while close/readback reports no live agent - Related readback mismatch. This report is specifically about tool-level parent mailbox/result delivery and lifecycle status.
- #26130 -
Parallel spawn_agent children can receive sibling prompt envelopes with fork_turns none - Related isolation issue. This report does not prove sibling prompt-envelope leakage, but it does show children behaving as sibling orchestrators despite
fork_turns: "none"and narrow scout prompts.
Impact
This makes subagents brittle for exactly the workflows where they are most valuable: parallel repo scouting, review/audit variance reduction, long-running research branches, and delegated planning. The parent thread cannot rely on subagent output unless a final payload actually arrives, and the failure mode consumes time/context while leaving no trustworthy result.
For user-facing Codex Desktop behavior, this feels like subagents silently disappearing or becoming confused about their role. It also makes it hard to file precise bug reports because parent-visible state and child-local state disagree.
Suggested fix direction
- Strengthen the active task boundary for spawned children, especially
fork_turns: "none"children with role-scoped prompts. Parent/team orchestration instructions should not cause a child to manage sibling agents unless that is explicitly delegated. - Always deliver a child terminal state to the parent mailbox, even if there is no final answer:
completed,interrupted,aborted,shutdown_without_result,not_found_after_spawn, etc., with child thread id and last known status. - Make
wait_agentable to surface terminal status updates for shutdown/interrupted children, not only final answer payloads. - Reconcile
list_agentsandclose_agentstates. If a listed/shutdown child has no live thread, return a structuredalready_shutdown/not_found_but_spawn_was_recordedsignal instead of a genericthread not foundfailure. - Expose capacity/status preflight before spawning, or include active capacity and live child list in the
agent thread limit reachedresponse. - Add regression coverage for:
fork_turns: "none"child with a narrow scout prompt must not callwait_agent/close_agentunless the prompt asks it to.- child interrupted after startup must generate a parent-visible terminal event.
- parent
wait_agentmust observe child terminal events. list_agents/close_agentlifecycle consistency after child shutdown or interrupted turn.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗