Skip to content

Completed subagents continue to count against thread limit #22779

Open

Description

@pengyou200902

What version of Codex CLI is running?

codex-cli 0.130.0

What subscription do you have?

Pro

Which model were you using?

ChatGPT 5.5

What platform is your computer?

Darwin 25.4.0 arm64 arm (MacBook Pro, M4 Max, MacOS Tahoe 26.4.1)

What terminal emulator and version are you using (if applicable)?

WarpTerminal v0.2026.05.13.09.15.stable_01

Codex doctor report

Not available. codex doctor --json is not supported by this installed CLI version; it exits with unexpected argument --json.

What issue are you seeing?

Completed subagents can continue to count against the per-session agent thread limit. After enough subagents have completed, a later spawn_agent call may fail with:

collab spawn failed: agent thread limit reached

This can happen even when earlier subagents have reached a final/completed state and are no longer doing work. Explicitly closing completed agents can free the quota, which suggests the quota is tied to thread removal/close rather than completion.

What steps can reproduce the bug?

Generic reproduction:

  1. Start a Codex session with subagents enabled.
  2. Spawn subagents sequentially or in batches.
  3. Wait for each spawned subagent to complete normally.
  4. Do not explicitly close the completed subagents.
  5. Continue spawning more subagents in the same session until the configured agents.max_threads quota is reached.

Expected result: completed subagents should no longer consume active spawn quota.

Actual result: later spawns can fail with agent thread limit reached until completed subagents are explicitly closed or the session is restarted.

A focused code-level reproduction is to set a low agents.max_threads, spawn an agent, drive it to TurnComplete, and then attempt another spawn. The second spawn should be allowed once the first agent is final.

What is the expected behavior?

Subagent quota should represent agents that are currently active/running or being reused for new work, not agents that have already reached a final status. Completed agents may remain addressable for history/listing purposes, but they should not block new spawns unless they are restarted and reacquire a quota slot.

Additional information

I investigated the relevant lifecycle/accounting path and found that spawned/resumed agents increment quota, while quota release was tied to explicit shutdown/close/thread removal. Normal completion updates agent status but does not release the quota slot.

I have a focused branch with a proposed fix and tests here:
https://github.com/pengyou200902/codex/tree/fix/subagent-thread-limit

Proposed approach:

  • Track counted agent IDs separately from retained agent metadata.
  • Release the quota slot when an agent reaches a final status, while preserving metadata.
  • Reacquire a quota slot before sending new work to an existing completed agent.
  • Handle resumed agents whose restored history already has a final status.

Validation run on the branch:

  • just fmt
  • just fix -p codex-core
  • cargo test -p codex-core release_spawn_slot_preserves_agent_metadata_until_thread_release
  • cargo test -p codex-core completed_agent_releases_max_threads_slot
  • cargo test -p codex-core spawn_slot

Per docs/contributing.md, I am opening this issue first and would only open a PR if maintainers invite one.

Activity

  1. added
    bugSomething isn't working
    subagentIssues involving subagents or multi-agent features
    on May 15, 2026
  2. pengyou200902 commented on May 17, 2026

    @pengyou200902
    Author

    Thanks for taking a look. I updated the branch after rebasing onto latest main.

    The current fix avoids the heavier watcher-based approach and instead releases the subagent quota slot from the normal session event path when an agent reaches a final status. Agent metadata is still retained, so completed agents remain listable/addressable, but they no longer block new spawns. If a completed agent receives new work later, it reacquires a slot first.

    I also kept the small Box::pin(Self::spawn_internal(...)) change in core/src/session/mod.rs; the forked-spawn regression still stack-overflows without it on the updated branch.

    Validation after rebase:

    • cargo test -p codex-core spawn_agent_fork_last_n_turns_keeps_only_recent_turns
    • cargo test -p codex-core completed_agent
    • cargo test -p codex-core spawn_slot
    • earlier full core lib run passed with cargo test -p codex-core --lib

    Branch: https://github.com/pengyou200902/codex/tree/fix/subagent-thread-limit

  3. debuggerone commented on May 22, 2026

    @debuggerone

    Now I am getting a "First spawning was denied because Full-History-Forks don't allow am explicit Worker-Type" while it now says that it found old closed agents - then closes them and then spawns 6 new ones.

    So the issue was fixed now as it seems on VS Code Version 26.519.32039

  4. debuggerone commented on May 22, 2026

    @debuggerone

    I am sure the "Full-History-Forks" denial has nothing to do with the old closed ones.. but who knows... maybe it blocks them and they are still running while new ones are spawned?

  5. antonreshetov commented on Jul 25, 2026

    @antonreshetov

    Confirming this is still reproducible in Codex Desktop on macOS.

    Environment:

    • Codex Desktop
    • codex-cli 0.144.6
    • macOS 26.5.1 (arm64)
    • Date: 2026-07-25

    Observed behavior:

    1. A long-running task used several specialized subagents sequentially.
    2. The agents finished and were shown as completed.
    3. A later attempt to spawn a researcher failed with: agent thread limit reached.
    4. Reusing an already completed agent via a follow-up task still worked, but spawning a new agent did not.

    This is especially confusing because the error does not report the configured maximum, which agents still occupy slots, or how to release/reclaim them. The public documentation also does not appear to describe this limit or its lifecycle.

    It would help if completed agents automatically released spawn capacity, or if the error exposed active/resident counts and a supported recovery action.

  6. GLGDLY commented on Aug 7, 2026

    @GLGDLY

    This is still reproducing in Codex Desktop on Windows11 today, any workarounds?

  7. costleya commented on Aug 13, 2026

    @costleya

    Reproducible on MacOS 26.5.2 (25F84), ChatGPT Version 26.803.61601

    I have a limit of 15. Even though 14 agents are "done", they remain not closed. The main agent claims there is no "close" operation it can use. Right now workaround is to increase to 50 parallel to work around these zombies.

  8. Manimap commented on Aug 13, 2026

    @Manimap

    I can confirm the same issue on windows 11 with and codex Version 26.803.81509.

  9. CKJ2026 commented on Aug 14, 2026

    @CKJ2026

    Confirming a closely related Codex Desktop lifecycle/persistence reproduction on macOS, with a read-only local state audit.

    Environment:

    • ChatGPT/Codex Desktop: 26.803.61601 (build 6396)
    • codex-cli 0.147.0-alpha.6.5
    • macOS 26.5.2 (build 25F84, arm64)
    • Date: 2026-08-13

    Observed sequence:

    1. The local history contained 260 child-agent spawn edges.
    2. Before cleanup, 17 child tasks were unarchived: 15 were already terminal (completed or interrupted) and only 2 were genuinely active / inProgress.
    3. I used the Desktop app's reversible archive operation only for the 15 terminal children. No rollout history was deleted and the local state database was not modified directly.
    4. The resulting state was 258 archived children and 2 active children.
    5. On a later read-only recheck, those remaining two children had themselves reached idle / completed and notLoaded / completed, but they still remained unarchived.
    6. The live collaboration tree contained only the root agent, while all 260 persisted spawn-edge records still reported open.

    This provides a concrete final-status transition where completion did not reconcile the persisted edge/lifecycle state. It appears consistent with the quota-accounting defect described in this issue, but Codex Desktop may also have a second persistence/UI reconciliation layer involved.

    Additional user-visible symptom: after the Mac is unlocked or restarted, historical completed subagents can appear as working; manually opening/clicking them can make them transition to done. I can prove the state mismatch above, but I have not captured CPU or memory sampling, so I am not claiming that every stale edge is still consuming compute.

    Questions for maintainers:

    1. Does current main contain an equivalent of the proposed counted_agent_ids / release-on-final-status fix from pengyou200902:fix/subagent-thread-limit?
    2. Should the persisted open edge and Desktop restart/unlock UI behavior be tracked in this issue, or as a separate Desktop state-reconciliation issue?
    3. Is there a supported close/reclaim or diagnostic operation that reports which retained agents actually count toward agents.max_threads?

    The proposed fork is currently far behind main, so I am treating it as design evidence only, not as an applicable or released fix.

  10. pomazanbohdan commented on Aug 14, 2026

    @pomazanbohdan

    Correction to my previous comment: the cleanup itself succeeded and did not immediately reproduce the failure.

    The observed sequence was:

    1. The backup-first cleanup completed successfully and removed the then-existing historical subagent state.
    2. Codex was relaunched.
    3. Parent task 019fea4e-4227-7810-be40-9afcc9a23aad then ran normally for a substantial period and spawned many new agents over multiple iterations. Those agents performed work and were explicitly completed/closed by the parent workflow.
    4. Only after this later workload did a fresh spawn fail with:
      collab spawn failed: agent thread limit reached.

    The failing attempt was captured in turn 019fff84-e58c-7591-b7f8-2f3010d3e920, spawn call call_BqDBs1lklX4C3NFAc6Sdkcm8. The parent was idle at inspection time, and the historical agents were no longer doing work.

    The runtime still recorded token_limit_reached=false and full_context_window_limit_reached=false, so this is not a model context/token failure. The issue is that a long sequence of child completions/closures still exhausted or failed to release the orchestration spawn quota. The cleanup/relaunch was therefore a successful reset, followed by a new quota-accounting failure under sustained agent churn.

    Expected behavior: once child agents are completed/closed, their slots should be released deterministically, regardless of how many sequential agents the parent has created. The quota must count only currently live/reusable handles, not historical completed/closed children.

  11. GLGDLY commented on Aug 14, 2026

    @GLGDLY

    This is still reproducing in Codex Desktop on Windows11 today, any workarounds?

    some addons from my observation, it seems mcp of subagents are also not correctly closed / even leaked, making codex occupying more and more RAM with running multiagent v2 for a period of time

  12. bmolina-agendapro commented on Aug 17, 2026

    @bmolina-agendapro

    Reproduced on Codex Desktop / codex-cli 0.147.0-alpha.6.5 on macOS (arm64).

    This is worse than quota accounting alone because the documented recovery operation is not consistently exposed to the root agent. The official Subagents documentation says Codex handles “closing agent threads” and explicitly recommends asking Codex to “close completed subagent threads.” In the affected session, however, the model-visible collaboration toolset contained spawn_agent, followup_task, send_message, interrupt_agent, list_agents, and wait_agent — but no close_agent or equivalent.

    Concrete result with max_concurrent_threads_per_session = 2:

    1. Spawn role A, wait for terminal completion, and consume its final result.
    2. Spawn role B, wait for terminal completion, and consume its final result.
    3. Attempt to spawn the next distinct role.
    4. Runtime returns: collab spawn failed: agent thread limit reached.
    5. Both previous children are completed, but root cannot close either because the documented close operation is absent from its tool surface.

    Reusing a completed thread with followup_task is only a partial workaround: it works when the same role/contract is needed again, but it is unsafe for a different role, model, sandbox, or responsibility. Raising the cap to the number of configured roles reduces failures but does not fix lifecycle accounting.

    Expected:

    • Completed children release admission capacity automatically, or the root always receives an explicit, reliable, idempotent close operation.
    • The docs describe the actual tool availability per client/runtime/version.
    • AgentLimitReached reports active, completed/resident, and closable counts plus an actionable recovery.
    • max_concurrent_threads_per_session clearly distinguishes open/resident capacity from active concurrency.

    This mismatch creates real token and latency cost: users build orchestration around a documented lifecycle capability, then discover only after long agent runs that the runtime cannot perform it. It also makes a basic sequential specialized-role pipeline substantially less reliable and more expensive than expected.

  13. delbyte commented on Aug 21, 2026

    @delbyte

    this is still happening!

    Platform: Ubuntu
    Codex CLI, latest

  14. pomazanbohdan commented on Aug 23, 2026

    @pomazanbohdan

    A current Windows reproduction confirms the quota symptom is part of the same lifecycle cluster: completed child rollouts can remain resident/open or reappear as pending_init, so spawn_agent returns agent thread limit reached even when visible work is done. See the UI evidence in #37042 and the residency diagnosis in #39694 and #34518.

  15. richardmears commented on Aug 25, 2026

    @richardmears

    This issue still persists now, even after app restart. UI shows no active subagents, but Codex states "the collaboration system returned agent thread limit reached despite showing no live child agent."
    Anecdotally, this seems to happen more often when the app updates and then an older parent thread is continued (i.e. it seems to happen less when the same version of the app is used throughout a single thread).

    Codex App Version 26.818.61809
    MacOS Tahoe 26.6 (25G72)

  16. tireiron commented on Sep 12, 2026

    @tireiron

    Repro on Codex CLI 0.153.4. The open threads (even though they're completed) are ~100, which is what I suspect the limit is, and there doesn't seem to be a way to clean them up. The agent was working around it by trying to reuse old unrelated threads. Starting a new session seems to be the most viable workaround, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsubagentIssues involving subagents or multi-agent features

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions