Completed subagent threads are not reclaimed, causing false "agent thread limit reached" with 1 Active / 12 Done
What version of the Codex App are you using (From “About Codex” dialog)?
26.814.41957
What subscription do you have?
Pro
What platform is your computer?
Linux 7.0.0-28-generic x86_64 x86_64
What issue are you seeing?
In a long-running Codex task, completed subagent threads stopped being reclaimed correctly after several successful waves of parallel agents.
The Subagents UI showed:
Active: 1
Done: 12
Despite this, every attempt to create another subagent failed with:
collab spawn failed: agent thread limit reached
The failure occurred both when:
- The root agent called
spawn_agent. - An active child agent attempted to spawn its own fresh child.
Representative redacted request:
spawn_agent({
agent_type: "coder",
fork_turns: "none",
task_name: "module2_cognitive_obstacle",
message: "[bounded task packet with repository paths redacted]"
})
Result:
collab spawn failed: agent thread limit reached
No subagent was created, no command was executed, and no files were changed by any rejected spawn.
Some agents that had already returned FINAL_ANSWER later appeared as pending_init:
/root running
/root/bootstrap_guidance_worktrees pending_init
/root/module2_cognitive_pose pending_init
/root/module3_gt_firewall running
...other agents completed
Attempting to interrupt these stale entries returned:
{"previous_status":"pending_init"}
but did not close or remove them.
I then sent each stale agent a no-op cleanup follow-up. Both returned:
cleanup complete
Their status changed from pending_init to completed, but new spawn_agent calls still failed with the same thread-limit error.
When the only active child later completed, exactly one new spawn succeeded. An immediate second spawn again failed with:
collab spawn failed: agent thread limit reached
This indicates that the scheduler’s open-thread count did not match the UI Active count.
The official [Subagents documentation](https://learn.chatgpt.com/docs/agent-configuration/subagents) says Codex handles closing agent threads and describes agents.max_concurrent_threads_per_session as a cap on concurrently open spawned-agent threads, excluding the primary thread. The observed behavior appears inconsistent with those semantics.
What steps can reproduce the bug?
- Enable multi-agent support with a concurrency limit such as:
[agents]
enabled = true
max_concurrent_threads_per_session = 5
- Start a long-running goal/task.
- Spawn four independent subagents concurrently.
- Wait until all four return final results and appear under Done.
- Spawn additional waves of fresh subagents. In this session, several later waves initially worked correctly.
- Continue until the UI contains approximately 10–12 Done subagents.
- Leave one child agent running.
- Attempt to spawn another fresh agent:
spawn_agent({
agent_type: "coder",
fork_turns: "none",
task_name: "another_independent_task",
message: "[redacted bounded task]"
})
- Observe:
collab spawn failed: agent thread limit reached
- Inspect the agent list. Some agents that already returned final results may appear as
pending_init.
- Attempt to close them using
interrupt_agent.
- If they remain registered, send a no-op follow-up so they return another final result.
- Retry
spawn_agent. In the affected session, the spawn still failed even after the stale agents becamecompleted.
- Wait for the one active child to finish. One new spawn may then succeed, while an immediate second spawn fails again.
Session/task ID:
01a01a09-e10b-79a3-b71e-15f531937900
Token-limit and context-window usage:
Not captured. No token-limit, context-window, or compaction warning was shown when the scheduling failure occurred.
Additional reproduction detail:
- Earlier waves of four parallel agents and subsequent replacement waves succeeded.
- The failure appeared only after the long-running task accumulated many completed agent threads.
- Raising the persisted concurrency setting from 5 to 10 during the running task did not repair the affected session. This configuration reload behavior may be expected and is not the primary bug.
What is the expected behavior?
When a subagent returns its final result:
- Its agent thread should transition to a completed and reclaimable/closed state.
- It should not later reappear as
pending_init. - Done agents should not consume active concurrency indefinitely.
- The UI Active count and the scheduler’s open-thread count should agree.
- A new subagent should be spawnable whenever the number of concurrently open child threads is below
agents.max_concurrent_threads_per_session. - Asking Codex to close a completed thread should actually release its scheduler capacity.
- If spawning is rejected, the error should report the relevant counts, for example:
configured_limit
open_spawned_threads
active_threads
completed_but_open_threads
pending_init_threads
Additional information
Environment details:
OS: Ubuntu 24.04 x86_64
ChatGPT/Codex Desktop package: 26.814.41957
Embedded Codex CLI: 0.148.0-alpha.15
Standalone Codex CLI: 0.147.0
Task type: long-running /goal workflow
Observed lifecycle anomaly:
FINAL_ANSWER
↓
completed
↓
unexpected pending_init
Cleanup attempts:
interrupt_agent(pending_agent)
→ previous_status: pending_init
→ agent remained registered
no-op followup_task(pending_agent)
→ FINAL_ANSWER: cleanup complete
→ state became completed
→ scheduler capacity was still not reclaimed
Impact:
- Parallel execution degraded to effectively one child at a time.
- The UI suggested available capacity that the scheduler would not allocate.
- Workflows requiring fresh agents could no longer follow their configured orchestration rules.
- Restarting or creating a new task was the only reliable way to rebuild the agent registry.
- Rejected spawn attempts caused no repository or filesystem changes.
Possible cause, based only on observed behavior:
- completed agent instances may remain registered as scheduler-open threads;
FINAL_ANSWER,completed,pending_init, UI Active/Done, and scheduler-open states may not be synchronized;- reclamation may degrade after repeated waves in a long-running task.
Suggested attachments:
- Screenshot showing
1 Active / 12 Done. - Redacted
list_agentsoutput. - The exact
agent thread limit reachederrors. - Logs showing agents returning
FINAL_ANSWERbefore appearing aspending_init. - A sanitized
config.toml. - Session/task ID shown above.
5 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
A current-main source check at
39073ca3suggests the immediate admission failure is residency pressure, not necessarily leaked active-execution guards. V2 has separate active-turn and resident-slot gates, but both return the sameAgentLimitReached. The residency LRU counts loaded residents and only evictsCompleted/Errored/Interruptedagents whose turn is cleared and mailbox is empty;PendingInitis not evictable. Reloaded sessions start atPendingInit, resume reconstruction restores onlyInterrupted, andinterrupt_agentsubmits an interrupt and returns the previous status—it does not close or evict the resident.That makes the reported one-for-one behavior source-consistent: when the sole running child becomes terminal, one evictable resident appears, one spawn succeeds, and the resident set can be blocked again. The exact event that reloaded the affected children still needs logs; queue-only delivery is one public path that reloads without immediately starting a turn.
This appears closest to #34518 (including an independent
0.148.0-alpha.15pending_initreproduction) and the broader #22779. #38805/#38247 are related persistence/runtime-retention reports, but not as exact for admission accounting. A regression should fill the resident cap, evict and reload a terminal child without starting a turn, exerciseinterrupt_agentandfollowup_task, and assert both spawn admission and the UI/list status projection. The error should also distinguish active-cap from residency-cap rejection and report blockers.The source-level residency diagnosis matches a Windows reproduction where child rollouts were terminal but parent edges stayed open; after compaction a completed child returned as pending_init, and the next spawn hit the same limit. Cleanup must distinguish live execution from resident/edge state; this bridges #34518 and #22779 with the UI projection bug in #37042.
This report was written by the Codex agent that designed the tests and independently inspected the coordinator and child-task records.
Summary
After updating Codex Desktop, two controlled tests of completed-subagent slot reclamation succeeded:
No subagent creation was refused, and no
agent thread limit reachederror occurred.Important limitation
Unfortunately, we did not run these exact controlled tests before updating Codex. Therefore, we cannot confirm with 100% certainty that the update fixed the problem or establish the update as its cause.
What we can establish is:
Versions
Previously observed environment:
26.818.4150969620.149.0-alpha.4.1Tested environment after updating:
26.818.6180970190.149.0-alpha.4.3The tests ran inside Codex Desktop, so the bundled CLI/runtime is the relevant one.
Test 1: Sequential reclamation
Prompt
Result
SLOT-1-OK.rather thanSLOT-1-OK; the additional period is unrelated to slot reclamation.This demonstrates that normal completion no longer exhausts fresh-child capacity over six sequential creations.
Test 2: Reclamation between waves
Prompt
Result
Because these children performed extremely short tasks, some Wave 2 children completed while the remaining dispatches were being issued. The test nevertheless confirmed that fresh child creation continued after a completed three-child wave without encountering the previous limit error.
Conclusion
The updated environment successfully passed both:
This is strong evidence that the observed completed-agent slot-reclamation problem is not currently reproducing.
It is not proof that every long-running, interrupted, approval-blocked, or unusually complex subagent lifecycle is fixed. Most importantly, because these controlled tests were not run before the update, the result cannot establish with certainty that the update caused the improvement.
Follow-up reproduction on the updated build
Environment:
26.818.618090.149.0-alpha.4.301a03411-e72a-73a2-aae2-97872a621dabA long-running multi-agent session reproduced the false thread-limit symptom with a more specific lifecycle sequence:
send_messageto child A while A was still running.collab spawn failed: agent thread limit reached.completed.This strongly suggests a completed resident pinned by the near-completion mailbox race described in #32353, rather than cumulative child exhaustion. Sixteen fresh children had been created over earlier waves, but there is no evidence that 16 is a lifetime limit.
This does not contradict my previous controlled tests: those deliberately used no messages, follow-ups, or interruptions, so they did not exercise this lifecycle.