close_agent can hang indefinitely on previously interrupted subagent, blocking parent thread

Resolved 💬 3 comments Opened Jul 3, 2026 by LmyNBL Closed Aug 5, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

A Codex Desktop parent thread can get stuck indefinitely when calling multi_agent_v1.close_agent on a previously interrupted/nonresponsive subagent. The affected subagent no longer appears to have an OS process, but close_agent remains blocked and the parent thread stays active / inProgress.

I am intentionally not pasting raw transcripts or private workspace paths in this public issue. I can provide logs through a private/support channel if useful.

Environment

  • Surface: Codex Desktop on macOS
  • Parent thread source: Codex Desktop
  • Parent thread id: 019f2670-631e-7fb1-b92e-69c8ca39a356
  • Parent thread title: 第一篇论文
  • App-bundled Codex version: codex-cli 0.142.5
  • Session cli_version: 0.142.5
  • Separately installed CLI version on PATH: codex-cli 0.139.0 (likely not involved because the stuck Desktop session reports 0.142.5)
  • Multi-agent version: v1

Affected agent

  • Subagent id: 019f27b2-5715-7b71-a395-40f1482aff47
  • Nickname: Ramanujan
  • Role: worker
  • Parent thread id: 019f2670-631e-7fb1-b92e-69c8ca39a356

Timeline / observed behavior

All times are from the local session transcript on 2026-07-03.

  1. Parent spawned worker subagent Ramanujan:
  • agent id 019f27b2-5715-7b71-a395-40f1482aff47
  1. Parent waited for the subagent and timed out repeatedly:
  • wait_agent([Ramanujan], timeout_ms=300000) returned {"status":{},"timed_out":true}
  • wait_agent([Ramanujan], timeout_ms=600000) returned {"status":{},"timed_out":true}
  1. Parent attempted to interrupt/redirect the subagent:
  • send_input(target=Ramanujan, interrupt=true, ...) returned a submission_id
  • A following wait_agent([Ramanujan], timeout_ms=120000) again returned {"status":{},"timed_out":true}
  1. Parent attempted to close the subagent:
  • close_agent(target=Ramanujan) hung for about 1031 seconds until user abort
  • A later close_agent(target=Ramanujan) hung again for about 602 seconds until user abort
  1. In a later heartbeat turn, another short-lived subagent (Kant, id 019f284a-5e20-7712-ae8f-e836d5835aaf) completed successfully and close_agent(Kant) returned immediately with the completed status.
  1. The parent then called close_agent(target=Ramanujan) again:
  • transcript last records the function call
  • no function call output follows
  • parent thread remains active / inProgress

Additional local observations

  • The child session transcript for Ramanujan exists and shows turn_aborted events.
  • The child transcript stopped updating after the earlier aborts.
  • A local process search did not reveal a separate OS process corresponding to Ramanujan or its agent id.
  • This suggests the stuck state is in Codex Desktop/app-server's logical subagent lifecycle, not in a visible local child process.

Expected behavior

close_agent should be safe/idempotent for a subagent that was interrupted, already aborted, or otherwise nonresponsive. It should not block the parent thread indefinitely.

Ideally it should either:

  • return the previous/terminal status,
  • mark the agent closed if it has no live worker,
  • or return a bounded timeout/error that lets the parent continue.

Actual behavior

close_agent can hang indefinitely on the old interrupted subagent. This blocks the parent thread and prevents the current turn from finishing.

Impact

  • Parent thread remains stuck as active / inProgress.
  • Automations/heartbeat workflows can be blocked.
  • Repeated attempts to close the same agent reproduce the hang.
  • The only practical workaround seems to be restarting Codex Desktop/app-server and avoiding future close_agent calls on that old agent.

Workaround used

  • Avoid calling close_agent on the stuck agent.
  • Use a new focused thread or restart Codex Desktop/app-server to clear the stuck app-server state.
  • For future automation prompts, avoid requiring new subagents/agent closing for simple running-lane monitoring.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #29937

Powered by Codex Action

joonyeonglim · 1 month ago

I took a look at this on current main and I think the hang is in the close path, not in the status read itself. I have a minimal patch prepared here if maintainers want a PR: https://github.com/joonyeonglim/codex/tree/fix/close-agent-shutdown-timeout

Findings:

  • multi_agent_v1.close_agent waits for agent_control.close_agent(agent_id) to return before it emits the close-end event.
  • The live-agent path in AgentControl::shutdown_live_agent sends Op::Shutdown and then awaits thread.wait_until_terminated() with no bound.
  • If the child thread is already interrupted/stuck and never reaches termination, the parent close call can wait indefinitely. That matches this issue and also overlaps with #25426 / #24389.

Patch shape:

  • Wrap thread.wait_until_terminated() in a 10s tokio::time::timeout.
  • On timeout, log a warning and continue through the existing cleanup path (remove_thread, forget_v2_residency, release_spawned_thread).
  • Keep the returned close result unchanged and avoid expanding tool output/schema.
  • The 10s timeout mirrors the existing app-server shutdown pattern in thread_lifecycle.rs.

Verification from my local branch:

  • just fmt passed.
  • git diff --check passed.
  • just test -p codex-core close_agent_submits_shutdown_and_returns_previous_status passed.
  • I also built local integration fixtures with cargo build -p codex-cli --bin codex -p codex-rmcp-client --bin test_stdio_server, then reran just test -p codex-core: 2912 passed, 1 failed. The remaining failure is unrelated and reproduces by itself on this checkout: apply_patch_cli_does_not_write_through_symlink_escape_outside_workspace.

I saw the CONTRIBUTING note that external code contributions are invitation-only, so I have not opened an unsolicited PR. Happy to open one from the branch above if maintainers want this direction.

LmyNBL · 1 month ago

This appears to be the same failure family as #29937, and I added the Desktop/app-server evidence from this issue there to keep the technical discussion consolidated.

Happy for maintainers to close this as a duplicate/corroborating report if that is preferred. I am leaving it open for now because it contains the Desktop-specific thread/lifecycle details and #29937 is also still open.