Title: Windows Desktop: stale subagents remain Working and every child starts the full local stdio MCP suite
What version of the Codex App are you using (From “About Codex” dialog)?
Codex app package: OpenAI.Codex_26.803.5235.0_x64
What subscription do you have?
Three local stdio MCP servers configured globally:
What platform is your computer?
windows
What issue are you seeing?
Environment
Codex Desktop / ChatGPT Desktop on Windows
Codex app package: OpenAI.Codex_26.803.5235.0_x64
Three local stdio MCP servers configured globally:
MarkItDown
brain-memory
brain-knowledge
Summary
After using many subagents, completed child tasks remain permanently shown as Working in the Desktop subagent panel.
The parent agent reports that no subagents are active and that all work is complete. However, the Desktop UI still shows many children as Working, and local persisted state still records them as open.
This is not only a visual issue: the app-server keeps or recreates task-host and MCP processes.
Evidence
The subagent panel shows completed children as Working for more than one hour.
The active orchestration state has no active child agents; only the root task is active.
Local thread_spawn_edges state contains:
open = 160
closed = 5
After fully closing Codex, terminating the confirmed Codex MCP Python processes, and launching Codex again, the fresh app-server immediately created:
4 node_repl task hosts
24 Python processes
12 MarkItDown processes
8 brain-memory processes
4 brain-knowledge processes
This pattern indicates that each task host starts the full globally configured MCP suite, even for child tasks that do not use those tools.
Steps to reproduce
Configure several local stdio MCP servers globally.
Run a long-lived Codex Desktop session that launches many subagents.
Let the child tasks finish and return results.
Observe that some children remain Working in the subagent panel.
Ask the parent to stop or close completed subagents. It may report that no active agents exist.
Inspect local process tree and persisted subagent state.
Restart Codex and observe that task-host/MCP processes are recreated.
Expected behavior
A child agent that has returned its final result should transition to Done/Closed.
Its persisted lifecycle state should also be closed.
MCP processes created solely for that child should be terminated when the child closes.
A child agent should be able to use an explicit, minimal MCP allowlist instead of inheriting every heavy global stdio MCP server.
Desktop restart should not restore completed children as active or Working.
Impact
This makes subagent-heavy workflows unreliable on Windows Desktop:
memory usage grows rapidly;
many unnecessary local MCP processes are created;
the subagent panel becomes inaccurate;
stale children may appear to remain active after completion;
restarting the app does not clear the underlying stale state.
I can provide redacted process-tree output, screenshots, and timestamps if useful.
What steps can reproduce the bug?
Environment
Codex Desktop / ChatGPT Desktop on Windows
Codex app package: OpenAI.Codex_26.803.5235.0_x64
Three local stdio MCP servers configured globally:
MarkItDown
brain-memory
brain-knowledge
Summary
After using many subagents, completed child tasks remain permanently shown as Working in the Desktop subagent panel.
The parent agent reports that no subagents are active and that all work is complete. However, the Desktop UI still shows many children as Working, and local persisted state still records them as open.
This is not only a visual issue: the app-server keeps or recreates task-host and MCP processes.
Evidence
The subagent panel shows completed children as Working for more than one hour.
The active orchestration state has no active child agents; only the root task is active.
Local thread_spawn_edges state contains:
open = 160
closed = 5
After fully closing Codex, terminating the confirmed Codex MCP Python processes, and launching Codex again, the fresh app-server immediately created:
4 node_repl task hosts
24 Python processes
12 MarkItDown processes
8 brain-memory processes
4 brain-knowledge processes
This pattern indicates that each task host starts the full globally configured MCP suite, even for child tasks that do not use those tools.
Steps to reproduce
Configure several local stdio MCP servers globally.
Run a long-lived Codex Desktop session that launches many subagents.
Let the child tasks finish and return results.
Observe that some children remain Working in the subagent panel.
Ask the parent to stop or close completed subagents. It may report that no active agents exist.
Inspect local process tree and persisted subagent state.
Restart Codex and observe that task-host/MCP processes are recreated.
Expected behavior
A child agent that has returned its final result should transition to Done/Closed.
Its persisted lifecycle state should also be closed.
MCP processes created solely for that child should be terminated when the child closes.
A child agent should be able to use an explicit, minimal MCP allowlist instead of inheriting every heavy global stdio MCP server.
Desktop restart should not restore completed children as active or Working.
Impact
This makes subagent-heavy workflows unreliable on Windows Desktop:
memory usage grows rapidly;
many unnecessary local MCP processes are created;
the subagent panel becomes inaccurate;
stale children may appear to remain active after completion;
restarting the app does not clear the underlying stale state.
I can provide redacted process-tree output, screenshots, and timestamps if useful.
What is the expected behavior?
Environment
Codex Desktop / ChatGPT Desktop on Windows
Codex app package: OpenAI.Codex_26.803.5235.0_x64
Three local stdio MCP servers configured globally:
MarkItDown
brain-memory
brain-knowledge
Summary
After using many subagents, completed child tasks remain permanently shown as Working in the Desktop subagent panel.
The parent agent reports that no subagents are active and that all work is complete. However, the Desktop UI still shows many children as Working, and local persisted state still records them as open.
This is not only a visual issue: the app-server keeps or recreates task-host and MCP processes.
Evidence
The subagent panel shows completed children as Working for more than one hour.
The active orchestration state has no active child agents; only the root task is active.
Local thread_spawn_edges state contains:
open = 160
closed = 5
After fully closing Codex, terminating the confirmed Codex MCP Python processes, and launching Codex again, the fresh app-server immediately created:
4 node_repl task hosts
24 Python processes
12 MarkItDown processes
8 brain-memory processes
4 brain-knowledge processes
This pattern indicates that each task host starts the full globally configured MCP suite, even for child tasks that do not use those tools.
Steps to reproduce
Configure several local stdio MCP servers globally.
Run a long-lived Codex Desktop session that launches many subagents.
Let the child tasks finish and return results.
Observe that some children remain Working in the subagent panel.
Ask the parent to stop or close completed subagents. It may report that no active agents exist.
Inspect local process tree and persisted subagent state.
Restart Codex and observe that task-host/MCP processes are recreated.
Expected behavior
A child agent that has returned its final result should transition to Done/Closed.
Its persisted lifecycle state should also be closed.
MCP processes created solely for that child should be terminated when the child closes.
A child agent should be able to use an explicit, minimal MCP allowlist instead of inheriting every heavy global stdio MCP server.
Desktop restart should not restore completed children as active or Working.
Impact
This makes subagent-heavy workflows unreliable on Windows Desktop:
memory usage grows rapidly;
many unnecessary local MCP processes are created;
the subagent panel becomes inaccurate;
stale children may appear to remain active after completion;
restarting the app does not clear the underlying stale state.
I can provide redacted process-tree output, screenshots, and timestamps if useful.
Additional information
_No response_
5 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
The
open = 160 / closed = 5split is useful because it suggests the durable edge table is being treated as authority when it should probably be a projection of lifecycle events plus live reconciliation.I would separate three states that are currently easy to collapse:
A child returning its final result should emit an immutable lifecycle event such as:
Then cleanup emits a separate resource-release event. The
thread_spawn_edges.openflag and Desktop "Working" badge become derived views, not independently mutable truths.On startup/resume, run a bounded reconciliation pass:
runningbut no owning runtime/process/lease exists, mark itstaleand do not recreate child resources automatically.openedge.That last distinction also helps the MCP amplification problem. MCP ownership should attach to the child attempt/resource lease, so
resource_state=releasedgives a deterministic teardown boundary. On restart, a historical child cannot accidentally become a reason to instantiate its full inherited MCP suite.A useful invariant would be:
I have been working on the same general evidence-vs-projection boundary in a local-first operational-memory compiler: source observations are retained and human-facing state is derived/reconciled rather than treated as self-authenticating truth: https://github.com/leadingproblemsolver/living-context-engine
LCE is not an agent lifecycle manager, but this issue is a strong example of why derived state (
open,Working) needs provenance and a reconciliation rule instead of becoming permanent authority.Additional confirmed reproduction:
A clean Codex Desktop launch starts with one MCP/node_repl stack.
Opening one historical parent chat with 51 stale subagents, without sending a message, causes
thread/resumeand creates additional full MCP stacks.Opening old child threads changes their UI state from Working to Done and triggers further
thread/resumecalls.Observed after one parent-chat load and inspection of a few children:
Codex logs correlate the launches with app_server thread/resume requests and MCP tool catalog initialization.
This is reproducible without launching a new task, a new subagent, or an MCP tool call.
Follow-up: local mitigation, validation, and architectural request
This is not a UI-only annoyance in my workflow.
I reproduced the historical-hydration path where completed children can be presented as
Workingagain and local tool/runtime activity can be re-materialized without any new user message. My earlier per-child stdio MCP topology amplified the process symptom, but it was not the root cause.Investigation cost
Approximate workflow telemetry for diagnosis, reproduction, patching, and validation:
These are not exact billed API tokens or exact ChatGPT subscription-quota consumption; that cannot be reconstructed client-side. However, the incident materially affected productivity and forced a subscription-tier increase during the investigation period.
Practical comparison
I moved from Claude Code expecting comparable multi-agent capability with a more economical workflow. In my day-to-day Claude Code workflow, bounded subagent orchestration had been predictable and practical.
In Codex Desktop, the equivalent workflow became operationally unsafe: reopening historical chats could restore stale child state and create uncertainty about whether completed work had truly stopped. This is my field experience, not a universal benchmark claim, but it is a major regression for a user relying on many small workers.
Experimental local mitigation
I published a sanitized, reproducible checkpoint:
It does not disable MCP, browser control, computer use, Node tools, or subagents. Instead it keeps lifecycle boundaries intact:
Validation: 4 lifecycle tests and 3 lazy-resume MCP integration tests passed. Opening four historical parent chats with completed children produced 0 new Python, 0 new Node, and 0 new
node_replprocesses, and no history-triggered MCP, child-spawn/resume, or model-transport references.This is an experimental local mitigation, not an official OpenAI fix or distributable Codex build.
IMPORTANT FOR CODEX USERS AND MAINTAINERS
HISTORICAL CHAT VIEWING MUST BE PASSIVE. A COMPLETED CHILD MUST NOT BE RESTORED AS A RUNNABLE RUNTIME JUST BECAUSE ITS PARENT CHAT WAS OPENED.
DEFAULT CHILDREN SHOULD BE LIGHTWEIGHT AND DENY-BY-DEFAULT FOR MCP SERVERS, PLUGINS, SKILLS, AND OTHER HEAVY TOOLING.
The orchestrator can retain its full toolset. Ordinary child workers should start with a minimal profile and bounded context; a specific MCP or plugin should be enabled only for the specialized child that actually needs it.
Suggested model:
If every child inherits the parent’s full tool surface and history by default, it creates an amplification risk: unnecessary process churn, configuration conflicts, avoidable context overhead, and potentially unnecessary agent/model usage.
Codex needs first-class lifecycle isolation and a safe lightweight-child default, while preserving deliberate opt-in to specialist tools.
Just asking but, isn't this issue a duplicate of the following?
#37042
#37041