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.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗