Codex desktop rehydrates closed, terminal subagents as Working after restart
Summary
Codex desktop 26.803.41515 (build 6321, Chromium 151.0.7922.76) incorrectly rehydrates completed and aborted subagents as Working after application startup.
The affected sessions are not live. Every inspected child rollout has a terminal event, every persisted spawn edge is closed, and backend lookup returns not_found. The Subagents panel nevertheless reconstructs historical children as active, including elapsed times of several days.
Impact
- False active-agent counts across affected parent conversations.
- Users cannot determine whether background work actually exists.
- Completed agents appear to be running for days.
- The panel may introduce UI/session-loading overhead when many historical children are reconstructed.
Evidence
- Historical child sessions inspected: 516
- Parent conversations affected: 11
- Terminal rollout events:
task_complete: 469turn_aborted: 47- Missing terminal events: 0
- Persisted
thread_spawn_edgesstate: closed: 516open: 0- SQLite integrity check:
ok - Backend lookup of affected historical agents:
not_found - One affected conversation (“Oanda”): 76 recorded subagents; all 76 end with
task_complete; the UI still shows them as working.
Reproduction
- Use a conversation that previously spawned many subagents and let them complete or abort.
- Open the Subagents panel. Completed children may be shown as Working, with long elapsed times.
- Quit and restart Codex desktop.
- Reopen the same conversation.
- The same terminal historical children are rehydrated as active.
- Compare persisted edge state:
sqlite3 ~/.codex/state_5.sqlite \
"SELECT status, COUNT(*) FROM thread_spawn_edges GROUP BY status;"
Expected result for the affected data: all records are closed. The UI still reports the agents as working.
Expected behaviour
On rehydration, the Subagents panel should honour terminal child rollout events (task_complete / turn_aborted) and the persisted thread_spawn_edges.status = closed state. Historical child-session existence alone must not imply a live working agent.
Actual behaviour
The desktop UI appears to infer Working from a historical subagent session or spawn record, ignoring terminal and closed state.
Additional observation
Resuming one representative stale child and explicitly closing it produced a shutdown notification. This suggests the live UI understands an explicit shutdown transition but fails to recognise already-terminal historical sessions during startup.
Scope and safety
This report is diagnostic only. No project files, databases, caches, conversations, or project artefacts were changed during investigation.
15 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Confirming the subagent respawn bug in ChatGPT/Codex for Windows app Version 26.803.41515
<img width="827" height="599" alt="Image" src="https://github.com/user-attachments/assets/d6e4adfa-0cf7-4d49-a2f5-8f7857a19204" />
The live collaboration registry contains no active child agents, and direct termination attempts for all seven return
not_found.The rows remain visible after navigating away from and back to the task.
I can reproduce this issue on Windows with Codex desktop 26.803.5235.0. I also submitted in-app feedback ID
019fe03e-8971-7df3-afe2-4ce8e6675f8c.Additional behavior that may help isolate the refresh path:
Without attaching private logs or local paths, desktop logs between 2026-08-01 and 2026-08-08 repeatedly recorded
Received turn/completed for unknown conversation(44 occurrences) andReceived turn/started for unknown conversation(86 occurrences). One inspected target was identified by the app as an ephemeral thread. No data loss was observed.Confirming this on macOS with Codex Desktop 26.803.41515 (build 6321), macOS 26.5.2 (25F84).
Additional reproduction evidence from an affected task:
The partial drop from 12 to 5 after restart suggests startup performs some reconciliation but does not consistently apply the authoritative terminal state to every restored row.
This evidence establishes a presentation / rehydration mismatch. It does not establish that the stale rows consume tokens or retain live processes.
Expected: startup should reconcile every restored child against authoritative lifecycle state and show only live children under Active / Working.
Additional reproducible evidence from Codex Desktop 26.803.5235.0 on Windows:
open.task_completeand 7turn_aborted; 0 were running.The packaged renderer explains the exact inflation. The collapsed summary computes:
The upstream view model exposes
active,waiting, anddone. When historical children are not hydrated/reconciled, they can fall through towaiting; the renderer then labels those waiting records as working. This is why the two visible counts still add up exactly to the historical child count even though none is live.A version- and hash-pinned local dry run split the presentation into
active/waiting/done/fallback-history and changed exactly the one renderer bundle; 5,751 other packaged files and all 37 native sidecar files remained unchanged. The installed app was not mutated by that diagnostic.Recommended upstream repair has two parts:
task_complete,turn_aborted, failure/cancel paths) during lifecycle updates and restore.status === "active"as working. Renderwaitingseparately (or omit it from the working count), and never infer unknown/unhydrated state as working.A compact regression fixture is: 127 stale waiting records, 39 hydrated done records, and 3 genuinely active records. The collapsed summary must report 3 working, not 130; after lifecycle reconciliation, the 127 terminal records should move to done/aborted rather than remain waiting.
Correction after tracing the public backend semantics on current
openai/codexmain:ThreadSpawnEdgeStatus::Opencan represent a child that is live or resumable. A normalTurnCompleteis therefore not, by itself, authority to close the spawn edge; explicit agent close/interrupt/removal paths must remain distinct.So please do not implement the earlier lifecycle recommendation as “close every edge on
task_complete.” The safe immediate presentation repair remains:status === "active"as working;waitingseparately (or exclude it from the working count);A backend follow-up should reconcile explicit close/interrupt/removal evidence and improve hydration, while retaining the public repo's resumable-agent behavior. The 127 waiting + 39 done + 3 active fixture still applies to the renderer regression: it must report 3 working, not 130.
Confirming on macOS with ChatGPT/Codex desktop 26.803.41515 (build 6321) and Codex CLI 0.147.0.
A local state audit found 63 persisted
thread_spawn_edges.status = openrows, while authoritative child-thread reads reported:notLoaded / completednotLoaded / interruptedidle / completedactive / inProgressThe UI displayed the historical children as Running across full app restarts.
Calling the supported
close_agentpath repaired 17 rows, but 45 historical children returnednot foundand could not be reconciled through the supported API. After the only genuinely active child completed, all remaining stale edges required a backed-up local status-index repair to restore an accurate panel. SQLite integrity remainedok; no conversation or child history was deleted.In-app feedback was also recorded without private logs:
019fe6aa-1214-7093-a812-0227dd259a13.This supports the existing renderer concern: unknown/unhydrated or resumable historical children must not be counted or labelled as actively Running. The panel should distinguish Active, Waiting/Resumable, and Done, and startup should safely reconcile explicit close/interruption evidence without treating every terminal child as non-resumable.
Confirming the same issue on macOS with ChatGPT/Codex desktop 26.803.41515.
In-app feedback ID:
019fa4ea-4bd3-75a2-b87d-e84aef7c4430Additional deterministic reproduction evidence:
The screenshots below were captured at 08:33 and 08:34, before and immediately after application restart.
<img width="1512" height="982" alt="Image" src="https://github.com/user-attachments/assets/75fafcd8-f8fa-446e-baaa-6108ce02de29" />
<img width="1512" height="982" alt="Image" src="https://github.com/user-attachments/assets/998d912f-3e21-4586-87df-d23c2956be83" />
Independent Windows reproduction on 2026-08-10. This matches the issue exactly.
Environment and visible behavior
usageLimitedblocked/ displayed as Goal stalledRecovery attempts that did not work
The panel still reported 25–27 agents as Active/Working. The count was not stable between refreshes.
Runtime/UI disagreement
The authoritative collaboration runtime reported only the parent agent as running. The three reachable recent children were already completed. Attempts to interrupt several older agents displayed as Working returned
not_found, including historical audit/research task names.This strongly indicates that terminal or nonexistent historical agents are being rehydrated as active UI records. The user cannot determine from the app whether token consumption has actually stopped.
Expected behavior
not_foundmust not be displayed as Working.Account impact and allowance-reset request
This goal exhausted the user’s available Codex allowance while spawning a much larger subagent tree than the user expected. The user is requesting review and restoration/reset of the consumed token allowance associated with this defective run.
I understand GitHub maintainers may not have account-billing tools. Please route this request to the appropriate OpenAI support team or provide a working account-support path for Codex Desktop; in this build, the in-app Help action opens only the Docs agent and does not offer a support-ticket flow.
No project source, secrets, email addresses, or full private thread identifiers are included in this public comment.
Confirming the same stale-subagent rehydration behavior on Windows Codex Desktop.
Additional reproduction pattern from a subagent-heavy workflow:
The important part is that the UI state disagrees with runtime evidence: the panel says Working, while process/lock checks show no active child execution. This can make users think agents are still consuming resources or holding writer slots when they are not.
Expected behavior: on conversation/app rehydration, the Subagents panel should reconcile against authoritative terminal/runtime state and render completed children as Completed (or historical), not Working. UI status should never be used as the sole indicator of active execution when the underlying child is already terminal.
I did not capture the exact Desktop build before leaving the machine, so I am not guessing a version. I can provide a screenshot and exact build later if useful.
Confirming the same restart/rehydration bug on Windows x64.
I am intentionally adding this to the existing issue instead of opening another duplicate because the reproduction matches the reported startup behavior closely.
Reproduction
Observed
After restart, historical child agents are rehydrated as Working even though no corresponding work has resumed and there is no active writer/process for them.
In the affected workflow, the UI state was therefore materially different from the execution state:
No file changes or resumed execution were observed from those stale rows. This looks like a presentation/rehydration-state bug rather than evidence that the old agents are actually running.
Operational impact
This is more than cosmetic for multi-agent workflows:
We now have to treat runtime/process terminal evidence as authoritative and mark the panel state as stale when the two disagree.
Expected
On app startup / conversation restore, completed historical children should be reconciled against terminal lifecycle state before rendering. A terminal child may remain visible as history, but it should be shown as Completed/Done, never Working, unless there is a current live execution handle.
If startup cannot confidently reconcile a historical row, a neutral state such as
Completed (restored)/Status unavailablewould be safer thanWorking.Exact Desktop build was not captured during this reproduction, so I am not guessing it. This occurred on Windows on 2026-08-12. No private project names, paths, prompts, thread IDs, or repository data are included in this report.
Confirmed on macOS with a smaller but directly comparable reproduction.
Environment
26.803.81509(build6415)15.7.7(build24G720)Observed
/root(the current parent task) as running.This confirms the UI state can disagree with both the live agent registry and the local process state on macOS. It also makes it hard for users to tell whether model work is still running remotely or whether the display is only stale.
In addition to reconciling the panel against terminal/closed task state on startup, please consider adding a visible Stop all subagents or Dismiss stale subagents action so users can recover from this state without database/cache manipulation.
Additional quantified Windows reproduction: https://github.com/openai/codex/issues/38364#issuecomment-5289195013
The key result is that 273 Active + 13 Done exactly matched 286 recursively persisted descendants, while all 286
thread_spawn_edgesrows remainedopen. The parent reported only one currently executing child, and the live process tree did not contain hundreds of agent runtimes.This supports the same root shape reported here: after restart/resume, cumulative persisted spawn history is being rehydrated/classified as live Working state. The fix should reconcile terminal/evicted/interrupted children passively and must not allocate MCP/tool runtime merely to determine their status.
Just asking but, isn't this issue a duplicate of the following?
#37042
#37041
#37426
Additional Windows evidence confirms the restart boundary: terminal task_complete/turn_aborted children reappear as Working while the live registry has no corresponding child. This bridges #37042's hydration diagnosis and #38364's large-scale panel drift.