multi_agent wait_agent/spawn_agent can block for ~7.5h; wait_agent timeout_ms not enforced during runtime stall

Open 💬 4 comments Opened May 28, 2026 by diogovalada

What version of the Codex App are you using (From “About Codex” dialog)?

26.519.81530

What subscription do you have?

ChatGPT Pro

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64

What issue are you seeing?

multi_agent_v1.wait_agent and adjacent spawn_agent tool calls can block the parent thread for hours. In the strongest observed case, wait_agent(timeout_ms=300000) returned only after 27,017.696 seconds, and still returned {"status":{},"timed_out":true}. An adjacent spawn_agent call in another subagent session took 26,994.842 seconds before returning an agent_id.

This appears to violate the user-visible timeout contract: a wait_agent call with timeout_ms=300000 should not block the parent for ~7.5 hours before reporting that it timed out.

The issue does not appear to be only a wait_agent per-tool bug, because spawn_agent calls stalled in the same quiet window and released at the same time. The evidence points to a shared multi-agent control-plane/tool-dispatch/runtime stall, with no end-to-end whole-tool deadline protecting the parent turn.

What steps can reproduce the bug?

I do not have a small deterministic repro, but I have concrete Codex JSONL evidence from local sessions.

Observed evidence:

  1. wait_agent(timeout_ms=300000) exceeded its requested timeout by hours.
file: C:/Users/<redacted>/.codex/sessions/2026/05/28/rollout-2026-05-28T05-46-57-019e6ce8-205f-7c50-9544-3ac26e049e68.jsonl
call line: 497
output line: 498
call_id: call_FrWUUz6SfgcfCfH5vSeDkqsP
args: {"targets":["019e6cff-7f1e-7803-a50c-b5f2eb72971f"],"timeout_ms":300000}
start: 2026-05-28T05:18:20.235Z
end:   2026-05-28T12:48:37.931Z
elapsed: 27017.696s
output: {"status":{},"timed_out":true}
  1. Adjacent spawn_agent call stalled in the same quiet window.
file: C:/Users/<redacted>/.codex/sessions/2026/05/28/rollout-2026-05-28T05-47-02-019e6ce8-34c0-7a33-8367-69330797145b.jsonl
call line: 567
output line: 571
call_id: call_KG8lMx4dpGHtXjaOLNacZ5RT
args: {"fork_context":false,"model":"gpt-5.5","reasoning_effort":"xhigh","message":"<redacted len=589>"}
start: 2026-05-28T05:18:50.645Z
end:   2026-05-28T12:48:45.487Z
elapsed: 26994.842s
output: {"agent_id":"019e6ea1-3421-79c3-8eb5-432bc82c7fbe"}
  1. Other same-window long calls:
wait_agent timeout_ms=900000
call_id: call_V3GOrqlj7zG9EgRKHTC31QkB
elapsed: 27873.523s
output: timed_out=true

spawn_agent
call_id: call_T9P4PVazFbWVXgKvFl398m5f
elapsed: 26988.260s

Local scan summary:

  • Scanned Codex JSONL logs under .codex/sessions and .codex/archived_sessions.
  • Paired thousands of function_call / function_call_output records by call_id.
  • The long stall window had no local Codex JSONL events from 2026-05-28T05:19:23.943Z to 2026-05-28T12:48:37.894Z.
  • Several stalled multi-agent calls released together at ~12:48Z.
  • Local Windows System/Application logs did not show sleep/resume/reboot/network transition evidence during the window.

Likely workload shape:

  • Multiple Codex Desktop subagents were running.
  • Parent/subagent sessions used multi_agent_v1.wait_agent and spawn_agent.
  • At least one wait_agent had a 5 minute timeout (300000ms), but the parent remained blocked for ~7.5 hours.

What is the expected behavior?

- `wait_agent(timeout_ms=300000)` should return within approximately 300 seconds plus small overhead, either with a completed status or a timeout result.
- `spawn_agent` should return promptly with an `agent_id` or fail with a bounded startup/initialization error.
- No multi-agent control-plane tool should be able to monopolize the parent turn indefinitely.
- If a lower-level Desktop/runtime/transport/tool-dispatch path stalls, the tool call should still be bounded by an end-to-end hard deadline and return a structured error/timeout.

Additional information

This looks distinct from, but related to, close_agent hangs such as:

This report is specifically about:

  • wait_agent.timeout_ms not bounding the whole tool call;
  • adjacent spawn_agent calls stalling in the same quiet window;
  • likely missing end-to-end deadlines around shared multi-agent/tool-dispatch/control-plane paths.

Public-source observations from openai/codex:

  • In codex-rs/core/src/tools/handlers/multi_agents/wait.rs, timeout_ms appears to wrap only the inner final-status wait. Other awaits, including event dispatch/status subscription/final event dispatch and outer tool execution, are not covered by a whole-tool deadline.
  • In codex-rs/core/src/tools/handlers/multi_agents/spawn.rs, spawn_agent appears to have no outer deadline around event dispatch, config/model/role work, spawn_agent_with_metadata, metadata reads, or final event dispatch.
  • The shared tool path also goes through tool runtime/registry/lifecycle/hook/event/persistence surfaces that appear to have unbounded awaits.

I cannot prove from public source alone whether the ~7.5h quiet window originated in Codex Desktop, app-server/gateway, Rust runtime lock/backpressure, lifecycle hooks, event dispatch, or persistence. But the public code appears to lack the hard end-to-end deadline needed to keep the parent turn responsive when any of those shared paths stalls.

Suggested fix direction:

  • Add a dispatcher/control-plane whole-tool deadline for multi-agent tools from tool invocation to function_call_output.
  • Start wait_agent timeout accounting before setup/event dispatch, or add a separate outer deadline that includes those phases.
  • Add bounded startup/initialization deadlines to spawn_agent.
  • Make collaboration event dispatch, lifecycle hooks, post-hooks, notification, and persistence paths bounded or best-effort where appropriate.
  • Add timing instrumentation for multi-agent tool phases so future reports can identify which await path stalled.

Related public issues that seem adjacent but not exact duplicates:

View original on GitHub ↗

4 Comments

zero-kotori · 1 month ago

I encountered what appears to be the same failure on a different platform and a current Codex CLI build.

Environment

  • Codex CLI: 0.144.1
  • Platform: macOS, ARM64
  • Tool surface: collaboration.spawn_agent

Observed behavior

  1. A direct spawn_agent call was made for a bounded, read-only source analysis task.
  2. The tool call produced no response and no agent identifier for 5,871 seconds (about 97 minutes and 51 seconds).
  3. The parent turn remained blocked in the "Thinking" state for the entire interval.
  4. The user had to abort the turn manually.
  5. After the abort, listing agents showed no corresponding child agent. This suggests the stall occurred before agent registration completed, rather than inside the child task.
  6. The local session event stream contains the tool invocation followed by the eventual turn-aborted event, with no tool result between them.

Timeout and cancellation gap

For this tool surface, the exposed spawn_agent schema contains only:

  • task_name
  • message
  • fork_turns

It exposes no timeout or deadline parameter. wait_agent(timeout_ms=...) cannot help until spawning has returned a target, and interrupt_agent also requires a registered target. While the synchronous tool call is pending, the parent cannot issue progress updates or a cancellation call.

Expected behavior

  • spawn_agent should return an agent identifier promptly or fail with a bounded, structured timeout.
  • The whole tool path, including dispatch and agent registration, should have an end-to-end deadline.
  • A stalled spawn should not monopolize the parent turn indefinitely.

Account identifiers, local paths, repository names, task contents, session identifiers, and call identifiers have been intentionally omitted.

AytuncYildizli · 1 month ago

Additional A/B data point: full-history fork blocked for 5h15m

Environment:

  • Codex CLI: 0.144.4
  • macOS 26.5, arm64
  • Surface: native collaboration.spawn_agent in a long-running workspace session

Observed:

  1. A fresh bounded read-only reviewer was spawned with fork_turns: "all".
  2. The spawn_agent call returned no agent identifier or structured error for 18,908.6s (about 5h15m).
  3. The parent turn remained blocked until the user manually aborted it.
  4. After abort, list_agents showed no corresponding child, suggesting the stall occurred before child registration completed.
  5. Retrying the same task category with fork_turns: "none" returned immediately and registered the child.

Expected: fork preparation/registration should have an end-to-end deadline and return either an agent identifier or a bounded structured error; a pre-registration failure should not monopolize the parent turn indefinitely.

This is a concrete A/B observation rather than a deterministic minimal reproduction. The all/none contrast may also connect this to the full-history fork path discussed in #20077.

jamesad · 1 month ago

Additional Windows + Codex Mobile Remote reproduction: spawn_agent blocked for 31m49s

Environment
  • Codex Desktop: 26.707.6957.0
  • Bundled CLI: codex-cli 0.144.0-alpha.4
  • Platform: Windows 10 Pro 25H2, build 26200.8655, x64
  • Client at incident time: ChatGPT mobile using Codex Remote; exact mobile build not captured
  • Tool: collaboration.spawn_agent
  • Fork mode: fork_turns: "all"
Observed chronology
  1. The user prompt requesting a multi-agent comparison reached the parent transcript at 2026-07-15T16:53:30.766Z.
  2. The parent emitted the first spawn_agent function call at 2026-07-15T16:53:42.692Z.
  3. No function result or registered child was returned until 2026-07-15T17:25:31.918Z.
  4. Elapsed time from function call to result: about 1,909.226s (31m49.226s).
  5. The affected parent turn recorded a total duration of 1,930,205ms (32m10.205s).
  6. For the stalled interval, Codex Mobile Remote could no longer access either the active chat or the connected Windows host, so the user could not steer or cancel the stuck turn remotely.
  7. Immediately after recovery, a second spawn_agent attempt was aborted after 2.5 seconds.
Evidence that the host and network stayed alive
  • Windows recorded no sleep, reboot, network-profile transition, WLAN disconnect, adapter reset, or application crash in the incident window.
  • The main Codex process did not restart.
  • Long-running local API and web processes remained continuous.
  • An independent web application on the same Windows host accepted live remote requests and persisted them throughout the blocked interval.
  • The relevant local services and listeners were still healthy after the Codex turn recovered.

This makes the Mobile Remote outage look like a user-visible consequence of the same unbounded multi-agent control-plane/tool-dispatch stall described in this issue, rather than a host, VPN, or LAN outage.

Expected behavior
  • spawn_agent should return a registered child or a structured timeout within a bounded interval.
  • A stalled multi-agent tool call should not make the connected host disappear from Codex Mobile Remote.
  • Mobile Remote should retain a way to cancel or recover a blocked parent turn.

Private thread IDs, local paths, account identifiers, and conversation content are intentionally omitted.

jamesad · 1 month ago

Follow-up: cross-thread Mobile Remote lockouts and agent-thread-limit evidence on Windows

Two additional reproductions occurred on the same Windows host and Codex Desktop build reported above.

Reproduction 1: unrelated top-level chat spawned agents

Chronology:

  1. At 2026-07-17T17:47:54Z, another top-level desktop chat spawned a subagent.
  2. At 2026-07-17T17:48:00Z, that chat spawned a second subagent.
  3. At 2026-07-17T17:48:07Z, the user reported that Codex Mobile Remote had disconnected.
  4. At 2026-07-17T17:49:07Z, the local app-server log recorded:

forwarding remote control connection closed transport event

The subagents belonged to a different top-level chat from the phone conversation that lost access. This indicates that the failure can affect the host-wide Remote connection, not only the parent turn that invoked spawn_agent.

Windows recorded no ChatGPT application crash and no sleep/wake event during the incident. The desktop app remained active.

Reproduction 2: nested spawn reached the agent-thread limit

Chronology:

  1. At 2026-07-17T22:51:11Z, another desktop chat successfully created a depth-2 subagent.
  2. At 2026-07-17T22:51:15Z, its next spawn_agent call failed with:

collab spawn failed: agent thread limit reached

  1. Codex Mobile Remote disconnected at the same time.
  2. Windows again recorded no ChatGPT application crash and no sleep/wake event.

This latest reproduction suggests that agent-slot saturation or task-tree reconciliation near the host-wide agent-thread limit may be a trigger. That is a chronology-based inference, not a claim about the unobserved provider-side implementation.

Expected behavior
  • Subagent activity in one desktop chat should not disconnect Mobile Remote from the entire host.
  • Reaching the agent-thread limit should return a bounded structured error to the invoking chat without disrupting unrelated chats or the host-wide Remote connection.
  • Mobile Remote should remain able to switch chats, steer work, and cancel a problematic turn.
  • If the Remote transport closes unexpectedly, the desktop app should reconnect automatically without requiring local access.

Private thread IDs, local paths, subagent task names, conversation contents, and account identifiers are intentionally omitted.