🚨 [URGENT][Remote SSH] 200+ terminal subagents resurrect as Running until opened one by one

Open πŸ’¬ 2 comments Opened Aug 10, 2026 by Lady-Lin
πŸ’‘ Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread β€” see the highlighted reply below.

Summary

Codex Desktop on Windows, connected to a Linux Codex host through Remote SSH, can restore hundreds of historical subagents as actively Running even though the authoritative collaboration registry reports no live child agents and almost every child rollout is terminal.

Opening one stale child thread makes the visible Running count decrease by exactly one. The persisted spawn edge remains open, so this appears to be per-child lazy UI reconciliation rather than a durable lifecycle transition.

This report contains only sanitized aggregate evidence. Project names, repository paths, prompts, task contents, thread IDs, account data, and screenshots are intentionally omitted.

Impact

  • The Subagents panel becomes operationally unusable: real active agents are hidden among hundreds of false Running entries.
  • Every stale entry displays a continuously increasing timer, making completed work appear to still be executing.
  • Users cannot safely decide whether Stop all would terminate real work.
  • Long-running, heavily delegated tasks accumulate persistent ambiguity.
  • There is no supported model-visible cleanup path in the affected MultiAgentV2 surface.
  • No evidence shows that these terminal children are still consuming model tokens. The confirmed defect is lifecycle/status visibility and reconciliation.

Environment

  • Client: Codex Desktop on Windows
  • Connection: Remote SSH
  • Host: Linux
  • Remote Codex App Server / CLI: 0.147.0
  • Windows desktop build: not exposed to the remote host
  • State database health: healthy; integrity and inventory checks passed
  • No matching background processes were found for the false Running count

Sanitized evidence

Affected parent A

  • Persisted descendant spawn edges: 50
  • Persisted edge status: 50 open
  • Child rollout terminal evidence:
  • 49 task_complete
  • 1 turn_aborted
  • Authoritative live collaboration registry: root only; 0 live descendants
  • Desktop panel: approximately 33 shown as Running

All visible Running descendants in this sample were false positives.

Affected parent B

  • Persisted descendant spawn edges: 233
  • Persisted edge status: 233 open
  • Child rollout evidence:
  • 223 task_complete
  • 6 turn_aborted
  • 4 without an observed terminal event
  • Desktop panel: approximately 222 Running and 10 Done

Even treating all four non-terminal rollouts as potentially unresolved, at least 218 displayed Running entries were false positives.

Strong reproduction clue: opening one child repairs only one row

  1. Open an affected parent task in Windows Codex Desktop over Remote SSH.
  2. Expand the Subagents panel.
  3. Observe many historical children shown as Running with live timers.
  4. Open one child that already has a terminal rollout.
  5. Return to the parent.
  6. The Running count decreases by exactly one.
  7. The corresponding thread_spawn_edges row is still open.

This behavior is repeatable one child at a time. It strongly suggests that opening a child forces a runtime/rollout read and updates only the client-side projection for that child.

State divergence

Observed pipeline:

~~~text
child rollout emits task_complete or turn_aborted
β†’ live collaboration registry no longer reports the child as running
β†’ thread_spawn_edges remains open/resumable
β†’ Remote SSH task restoration projects the unresolved/open record as Running
β†’ Desktop keeps incrementing the historical startedAt timer
β†’ opening that child forces lazy reconciliation
β†’ one UI row moves out of Running, but persisted edge remains open
~~~

An open spawn edge may legitimately mean resumable, so task_complete alone must not be treated as authority to destroy history or automatically close every resumable child. The presentation bug is that open, waiting, resumable, unknown, and unhydrated records are being presented as actively Running.

MultiAgentV2 lifecycle gap

The affected V2 model tool surface exposes:

~~~text
spawn_agent
send_message
followup_task
interrupt_agent
list_agents
wait_agent
~~~

It does not expose close_agent or an equivalent idempotent retire/reconcile operation. Older executions that used the V1 close_agent path produced closed spawn edges, while completed V2 children commonly remain open/resumable.

This means an orchestrator can verify that a child is no longer live, but cannot durably retire that accepted child or clean the panel through the supported V2 surface. interrupt_agent is not an equivalent: it interrupts a turn and leaves the Agent available.

Expected behavior

  • Running must mean a child has an actually active execution turn.
  • Waiting/resumable children must be displayed separately or excluded from the Running count.
  • Terminal or unhydrated history must never default to Running.
  • Remote SSH restoration must batch-reconcile all descendant rows; users must not open hundreds of children one by one.
  • Timers must stop when execution is no longer active.
  • V2 should expose a safe, idempotent lifecycle close/reconcile operation, or the Host should retire accepted children automatically according to explicit lifecycle policy.
  • History and resumability must be preserved unless an explicit close is requested.

Suggested safe repair

  1. During parent-task restore, batch hydrate descendant runtime/latest-turn state from the remote Host.
  2. Derive the Running counter only from confirmed active execution state, never from edge status open by itself.
  3. Represent Waiting/Resumable/Unknown explicitly.
  4. Apply terminal notifications to the parent projection without requiring child navigation.
  5. Expose an idempotent V2 close/reconcile operation that preserves history and reports partial failures.
  6. Never repair this by deleting rollouts or blindly closing every task_complete edge.

Regression canary

Create one parent with four children:

  • one genuinely active;
  • one idle and intentionally resumable;
  • one task_complete;
  • one turn_aborted.

After Remote SSH disconnect/reconnect and full Desktop restart:

  • Running must equal 1;
  • idle/resumable must not be labelled Running;
  • both terminal children must remain inspectable but not active;
  • opening any child must not change the aggregate status;
  • explicit V2 retirement must be idempotent and must not delete history.

Related reports

This Remote SSH report is related to, but adds a distinct remote hydration and V2 lifecycle data point beyond:

  • #37563
  • #35209
  • #19197
  • #32443
  • #25341

Safety and privacy

  • Read-only diagnostics only.
  • No SQLite mutation was performed.
  • No project source or configuration was changed.
  • No private paths, task identifiers, prompts, business data, secrets, or account identifiers are included.

View original on GitHub β†—

2 Comments

github-actions[bot] contributor Β· 17 days ago

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

  • #37729
  • #37042
  • #37814
  • #37563
  • #37222

Powered by Codex Action

VirgilMing Β· 17 days ago

Confirming the same per-child lazy reconciliation behavior in a local Remote SSH setup.

Environment/topology:

  • Windows Codex Desktop from the Microsoft Store
  • Remote SSH connection to Arch Linux running under WSL on the same physical Windows machine
  • The affected parent conversation had spawned multiple subagents (from Sol Ultra)

Observed behavior after a cold Desktop start:

  1. Previously completed subagents are shown as still Running in the parent Subagents aggregate view.
  2. Refreshing/reopening the aggregate Subagents view does not reconcile their status.
  3. Opening one individual subagent's detail view causes Desktop to recognize that specific child as stopped/completed.
  4. Returning to the aggregate view shows exactly that one entry corrected; the other stale entries remain Running.
  5. Repeating this child-by-child corrects them one at a time.

This is therefore reproducible without a genuinely remote host or WAN/network interruption: the SSH target is an Arch WSL instance on the same machine. The behavior strongly matches the per-child lazy hydration/reconciliation described in this issue, with no apparent batch reconciliation at the aggregate parent view.