TUI /agent accumulates ghost subagent threads; stale entries open blank while API returns 'agent not found'
Summary
After upgrading to codex-cli 0.117.0, persistent subagent/collab workflows can accumulate ghost thread entries in /agent.
The broken behavior has two visible symptoms at the same time:
/agentshows many historical subagent threads instead of only the currently live ones.- Some of those entries open as blank/empty threads with no transcript, while the tool/API layer already treats the same thread ids as dead (
agent with id ... not found).
This makes it hard to tell which subagent threads are actually alive, and long-running orchestrated workflows start to degrade because the UI/thread list diverges from live thread state.
Possibly related, but not identical, to:
- #14162
- #15306
Environment
- Codex:
codex-cli 0.117.0 - Platform: macOS 15.7.4 (
Darwin 24.6.0, arm64) - Auth: ChatGPT account via normal local Codex auth
- Workflow: TUI collab / persistent subagent threads (
/agent,spawn_agent,send_input,wait_agent)
What I’m seeing
In a persistent collab/orchestrator workflow, old subagent handles become invalid after restart/resume or after enough respawn churn. That part is survivable because the orchestrator can respawn them.
The problem is that the /agent UI keeps showing many stale historical threads anyway. Some of those stale entries open as blank threads with no visible content. Meanwhile the tool layer already returns errors such as:
agent with id 019d25da-1d65-7621-b753-6adf4fc7b52f not foundagent with id 019d25e8-a744-7331-9e73-c303db8c0c31 not foundagent with id 019d25f6-7cc2-7f70-ad91-b331b1645c6b not foundagent with id 019d2604-c1a3-7020-9398-3d371cd16e74 not found
So there is a state split:
- UI/thread picker still surfaces the dead entries
- API/tool layer already considers them gone
- opening some of those entries gives an empty/blank thread view instead of a clear stale-thread error or automatic pruning
Repro sketch
I do not have a tiny standalone repro yet, but this reproduces reliably in a long-running collab setup:
- Start a persistent multi-subagent workflow in TUI.
- Reuse the same subagent roles across multiple cycles (
send_input+wait_agent). - Restart/reattach the TUI at least once, or continue long enough that some stored handles become invalid and need respawn.
- Let the orchestrator respawn stale threads when it gets
agent ... not found. - Open
/agent.
Observed result:
/agentnow contains many historical/stale thread entries.- some of them open as blank/empty threads.
- only a subset correspond to actually live handles.
Expected behavior
Any of these would be acceptable, but the current split-brain state is not:
/agentshould only show live/rehydratable threads.- If a thread id is already dead, the UI should mark it stale or remove it automatically.
- Opening a stale entry should show an explicit stale-thread error, not a blank thread.
- Respawning a role thread should not leave ghost entries that look selectable but are not backed by a live thread.
Local evidence
During cleanup/reset, I had to close current live threads and recreate only four fresh ones. After cleanup, the live handles were:
- architect:
019d340b-7a50-7481-a6d0-1450441bd84c - planner:
019d340c-b77d-79f2-b6a5-25868eeb8112 - coder:
019d340d-a216-7190-a0a4-cefe6697a779 - reviewer:
019d340e-9969-7d30-b27b-f2259475c0f1
Recent local audit log excerpts still show the churn that preceded the ghost entries:
architect:
28.03.2026 10:22:39 019d3351-78d9-7062-90b5-a47c8699d646 respawn
28.03.2026 12:10:23 019d33b4-8150-7842-a1d8-9f2ea9b8fdec respawn
28.03.2026 13:45:37 019d340b-7a50-7481-a6d0-1450441bd84c respawn cleanup_reset
planner:
28.03.2026 10:36:59 019d335e-b8ef-7c51-8559-2942c757175d respawn
28.03.2026 13:18:48 019d33f2-5dd3-7121-87fb-7b50cdefb8d7 respawn
28.03.2026 13:46:36 019d340c-b77d-79f2-b6a5-25868eeb8112 respawn cleanup_reset
coder:
28.03.2026 10:51:01 019d336b-ebe4-7001-b397-78bd522d679f respawn
28.03.2026 11:41:05 019d3399-b60a-7db0-a453-4f0feb98f987 respawn
28.03.2026 13:47:41 019d340d-a216-7190-a0a4-cefe6697a779 respawn cleanup_reset
reviewer:
28.03.2026 10:17:58 019d2604-c1a3-7020-9398-3d371cd16e74 respawn
28.03.2026 11:50:54 019d33a2-f32b-7e81-b302-fc7957c986b8 respawn
28.03.2026 13:49:25 019d340e-9969-7d30-b27b-f2259475c0f1 respawn cleanup_reset
Why this matters
This is not just cosmetic. In a long-running orchestration flow, the operator cannot trust /agent anymore:
- some visible threads are dead
- some dead threads open blank
- the live set is smaller than what the UI suggests
- cleanup becomes guesswork
If needed, I can add a screenshot of the /agent list showing the ghost entries and the blank thread behavior.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Additional data point from the same environment.
I cannot directly upload the chat screenshot binary via
ghfrom this CLI session, so here is the exact screenshot summary plus the verified config fact.Screenshot summary
In the
/agent/Subagentspicker, the list is showing entries numbered7through14, so there are at least14subagent entries visible in the same workspace/session history.The visible tail in the screenshot is:
7. Rawls [default] 019d33b4-8150-7842-a1d8-9f2ea9b8fdec8. Dewey [default] 019d335e-b8ef-7c51-8559-2942c757175d9. Gauss [default] 019d33f2-5dd3-7121-87fb-7b50cdefb8d710. Russell [default] 019d25da-1d65-7621-b753-6adf4fc7b52f11. Tesla [default] 019d340b-7a50-7481-a6d0-1450441bd84c12. Hilbert [default] 019d340c-b77d-79f2-b6a5-25868eeb811213. Dewey [worker] 019d340d-a216-7190-a0a4-cefe6697a77914. Popper [worker] 019d340e-9969-7d30-b27b-f2259475c0f1Some of these are current fresh handles; some are older stale handles from earlier respawns. The bug is that they are shown together in
/agent, and some stale ones open as blank threads.Config cap mismatch
This is not just "lots of old history" in the abstract. The active workspace config cap is explicitly
7, not14:CODEX_HOME:/Users/palvaleri/.ai-profiles/worktrees/racex_tooling/Users/palvaleri/.ai-profiles/worktrees/racex_tooling/config.toml:31[agents] max_threads = 7Global fallback config also has the same cap:
/Users/palvaleri/.codex/config.toml:29[agents] max_threads = 7So the UI showing at least
14subagent entries in this state strongly suggests ghost/stale thread entries are not being pruned or excluded by the configured thread cap.If useful, I can later add the actual screenshot file once I have a direct filesystem path or upload URL instead of an in-chat image.
Attaching the screenshot as an inline image.
This is the
/agentpicker state referenced above. It shows at least 14 subagent entries in the same workspace, despite the active config cap being[agents] max_threads = 7, and it includes both fresh handles and older stale handles in the same visible list.!Screenshot: /agent picker showing ghost and fresh subagent entries