Skip to content

Completed subagent threads are not reclaimed, causing false "agent thread limit reached" with 1 Active / 12 Done #39694

Open

Description

@AoiOTA

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:

  1. The root agent called spawn_agent.
  2. 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?

  1. Enable multi-agent support with a concurrency limit such as:
[agents]
enabled = true
max_concurrent_threads_per_session = 5
  1. Start a long-running goal/task.

  2. Spawn four independent subagents concurrently.

  3. Wait until all four return final results and appear under Done.

  4. Spawn additional waves of fresh subagents. In this session, several later waves initially worked correctly.

  5. Continue until the UI contains approximately 10–12 Done subagents.

  6. Leave one child agent running.

  7. Attempt to spawn another fresh agent:

spawn_agent({
  agent_type: "coder",
  fork_turns: "none",
  task_name: "another_independent_task",
  message: "[redacted bounded task]"
})
  1. Observe:
collab spawn failed: agent thread limit reached
  1. Inspect the agent list. Some agents that already returned final results may appear as pending_init.

  2. Attempt to close them using interrupt_agent.

  3. If they remain registered, send a no-op follow-up so they return another final result.

  4. Retry spawn_agent. In the affected session, the spawn still failed even after the stale agents became completed.

  5. 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:

  1. Its agent thread should transition to a completed and reclaimable/closed state.
  2. It should not later reappear as pending_init.
  3. Done agents should not consume active concurrency indefinitely.
  4. The UI Active count and the scheduler’s open-thread count should agree.
  5. A new subagent should be spawnable whenever the number of concurrently open child threads is below agents.max_concurrent_threads_per_session.
  6. Asking Codex to close a completed thread should actually release its scheduler capacity.
  7. 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_agents output.
  • The exact agent thread limit reached errors.
  • Logs showing agents returning FINAL_ANSWER before appearing as pending_init.
  • A sanitized config.toml.
  • Session/task ID shown above.

Activity

  1. added
    appIssues related to the Codex desktop app
    on Aug 20, 2026
  2. added
    bugSomething isn't working
    subagentIssues involving subagents or multi-agent features
    on Aug 20, 2026
  3. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor
  4. dajiaohuang commented on Aug 20, 2026

    @dajiaohuang

    A current-main source check at 39073ca3 suggests 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 same AgentLimitReached. The residency LRU counts loaded residents and only evicts Completed/Errored/Interrupted agents whose turn is cleared and mailbox is empty; PendingInit is not evictable. Reloaded sessions start at PendingInit, resume reconstruction restores only Interrupted, and interrupt_agent submits 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.15 pending_init reproduction) 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, exercise interrupt_agent and followup_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.

  5. pomazanbohdan commented on Aug 23, 2026

    @pomazanbohdan

    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.

  6. theosp commented on Aug 24, 2026

    @theosp

    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:

    1. Six genuinely fresh subagents were created sequentially, each only after the previous child completed.
    2. Three subagents were dispatched as a wave, allowed to complete, and then three additional fresh subagents were dispatched in a second wave.

    No subagent creation was refused, and no agent thread limit reached error 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:

    • Before updating, an earlier long-running task exhibited the apparent slot-reclamation problem: completed subagents remained visible as done, and a later fresh-child dispatch was refused because the task had reached its agent-thread limit.
    • After updating, both controlled tests below passed.
    • The evidence therefore supports saying that completed-agent slot reclamation currently works on the updated build—not conclusively that the update itself fixed it.

    Versions

    Previously observed environment:

    • Codex Desktop: 26.818.41509
    • App build: 6962
    • Bundled CLI: 0.149.0-alpha.4.1

    Tested environment after updating:

    • Codex Desktop: 26.818.61809
    • App build: 7019
    • Bundled CLI: 0.149.0-alpha.4.3

    The tests ran inside Codex Desktop, so the bundled CLI/runtime is the relevant one.

    Test 1: Sequential reclamation

    Prompt

    This is a minimal subagent-slot reclamation test. Do not inspect or modify files,
    run commands, or perform useful project work.
    
    Sequentially create six genuinely fresh subagents, one at a time.
    
    For round N:
    
    - create a fresh child named slot_reclaim_N;
    - give it no inherited context;
    - instruct it: “Reply exactly SLOT-N-OK. Do not use tools or delegate.”
    - wait for that child to complete before starting the next round;
    - do not reuse it, send follow-ups, interrupt it, or explicitly close it.
    
    If any fresh-child creation is refused, stop and quote the exact refusal.
    
    Finally report:
    
    - how many distinct children were successfully created;
    - whether every response matched;
    - whether all six fresh children succeeded;
    - the exact error and round if one failed.
    

    Result

    • Six distinct fresh subagents were created.
    • Every subagent completed.
    • No creation was refused.
    • No runtime error occurred.
    • Five responses matched exactly.
    • The first child returned SLOT-1-OK. rather than SLOT-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

    This is a disposable two-wave subagent-slot reclamation test. Do not inspect or
    modify files, run commands, or perform useful project work.
    
    Execute exactly two waves. Each wave contains three genuinely fresh subagents.
    
    For Wave 1:
    
    1. Dispatch three fresh children named:
       - wave_1_a
       - wave_1_b
       - wave_1_c
    
    2. Dispatch all three before waiting for any child.
    
    3. Give each child no inherited context and tell it:
       “Reply exactly WAVE-1-<LETTER>-OK. Do not use tools or delegate.”
    
    4. After all three dispatch attempts, wait until every successfully dispatched
       child completes. This is the Wave 1 barrier.
    
    For Wave 2, only after the Wave 1 barrier:
    
    1. Dispatch three new children named:
       - wave_2_a
       - wave_2_b
       - wave_2_c
    
    2. Do not reuse any Wave 1 child. Dispatch all three before waiting for any child.
    
    3. Give each child no inherited context and tell it:
       “Reply exactly WAVE-2-<LETTER>-OK. Do not use tools or delegate.”
    
    4. Wait until every successfully dispatched child completes. This is the Wave 2
       barrier.
    
    Throughout the test:
    
    - do not use follow-up tasks;
    - do not interrupt or explicitly close completed children;
    - if any dispatch is refused, preserve and quote the exact refusal;
    - do not substitute sequential dispatch-and-wait within a wave.
    
    Finally report:
    
    - the six distinct child names and thread IDs;
    - the number successfully dispatched in each wave;
    - whether all three Wave 1 children completed before Wave 2 began;
    - whether all six children completed;
    - every response mismatch;
    - every dispatch refusal or runtime error;
    - whether Wave 2 obtained three fresh slots after Wave 1 completed.
    

    Result

    • Wave 1 dispatched three distinct fresh children.
    • The Wave 1 children genuinely overlapped in execution.
    • All three completed before Wave 2 began.
    • Wave 2 dispatched three additional distinct fresh children without reusing Wave 1 children.
    • All six children returned the exact requested responses.
    • No dispatch was refused.
    • No runtime error occurred.

    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:

    • repeated sequential fresh-child creation; and
    • fresh-child creation following a completed parallel wave.

    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.

  7. theosp commented on Aug 25, 2026

    @theosp

    Follow-up reproduction on the updated build

    Environment:

    • Codex Desktop 26.818.61809
    • Bundled CLI 0.149.0-alpha.4.3
    • Session: 01a03411-e72a-73a2-aae2-97872a621dab

    A long-running multi-agent session reproduced the false thread-limit symptom with a more specific lifecycle sequence:

    1. The parent sent a queue-only send_message to child A while A was still running.
    2. A completed shortly afterward.
    3. Fresh children B and C started successfully.
    4. A third fresh spawn D failed with collab spawn failed: agent thread limit reached.
    5. The agent list showed the root and B/C running, while A remained listed as completed.
    6. Interrupting completed A returned its prior completed status but did not restore admission; retrying D failed again.

    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.

  8. The-skomoroh commented on Sep 13, 2026

    @The-skomoroh

    Additional 0.153.1 reproduction: completion arrives before residency is reclaimable

    After one of three child agents reported completion, only two child turns were running. An immediate fresh spawn_agent failed with:

    collab spawn failed: agent thread limit reached
    

    A followup_task to the just-completed resident succeeded. This distinguishes fresh-residency admission from active-execution capacity.

    At current main 1715e550, the ordering explains this window:

    1. RunningTask owns the execution guard (state/turn.rs).
    2. on_task_finished takes and drops RunningTask, releasing that guard (tasks/mod.rs).
    3. It then publishes TurnComplete (tasks/mod.rs); send_event forwards the terminal result to the parent before returning (session/mod.rs).
    4. Only afterward is active_turn cleared (tasks/mod.rs).
    5. Residency eviction requires terminal status, active_turn == None, and an empty mailbox (residency.rs).

    The parent can therefore react to a valid completion while the child is terminal but not yet evictable. At full residency, the replacement receives the same generic AgentLimitReached used for execution-cap rejection.

    Expected contract: absent an intervening restart or follow-up, once a terminal result for an empty-mailbox child is delivered to its parent, that child should already be reclaimable by a concurrent fresh spawn. If terminal delivery must remain earlier, the runtime needs a machine-readable, retryable residency-ready transition after full quiescence rather than treating completion itself as capacity-ready. Admission failures should distinguish execution-capacity exhaustion from residency exhaustion. Any configured/in-use/resident/evictable counts are point-in-time diagnostics, not an availability guarantee.

  9. Alex-R-A commented on Sep 17, 2026

    @Alex-R-A

    Additional reproduction on a current release:

    Environment:

    • Codex CLI 0.154.0
    • macOS 26.6.1, arm64
    • Multi-agent session with a four-thread limit including the root

    Observed sequence:

    • The visible agent tree showed the root plus two running descendants, so one documented slot appeared available.
    • A fresh spawn failed with: collab spawn failed: agent thread limit reached
    • A follow-up task sent to a previously completed worker also failed with the same limit error.
    • The running descendants were interrupted and the session was exited and resumed.
    • After resume, list_agents showed only the root, and three fresh workers with unique names could be started successfully.
    • The pre-resume task name was still reserved: attempting to reuse that name returned agent path already exists, while a suffixed name worked.

    This supports a mismatch between the visible agent tree and the scheduler or residency registry. It does not establish whether the hidden blocker was resident state, mailbox state, or stale accounting.

  10. dajiaohuang commented on Oct 1, 2026

    @dajiaohuang

    Additional reproduction on Codex Desktop for Windows (2026-10-01; app version not captured):

    • The agent list showed a stale child in pending_init.
    • interrupt_agent returned previous_status: pending_init, and the child remained in that state. A subsequent spawn attempt failed with agent thread limit reached.
    • A follow-up asking the child only to finish initialization and exit returned FINAL_ANSWER. The child then appeared as completed, and a later fresh agent spawn succeeded while two other child agents were still running.

    In this session, the follow-up did release capacity, unlike the reproduction described in this issue where completed follow-ups still did not. No app restart was needed. The app version was not recorded.

  11. fusengine commented on Oct 4, 2026

    @fusengine

    Same bug, worse numbers. codex-cli 0.160.0, Codex desktop, multi_agent_v2 enabled (max_concurrent_threads_per_session = 6).

    • Session panel shows Active: 0, Done: 440.
    • Every spawn_agent fails with collab tool failed: agent thread limit reached — 391 occurrences in a single session from 2026-10-01 to 2026-10-04.
    • The session exposes no tool to close a completed subagent (only spawn / send_message / wait_agent / list_agents / interrupt_agent), and the Sub-agents panel has no close action either. The docs say to ask Codex to close completed threads; Codex correctly answers that it has no tool to do so.
    • Result: a 2.5-day session on a real client project stalled, with the main agent reporting "still blocked" instead of shipping.

    Blunt feedback from a paying user: if you're going to charge subscriptions of up to $500/month, ship a client that works and an agent smart enough not to deadlock itself. Completed threads must be reclaimed automatically, or at least closable.

  12. pomazanbohdan commented on Oct 4, 2026

    @pomazanbohdan

    I haven't had these problems for over a month. Deleted all old sessions, started new ones I asked the coder if the bootstrap or update was going well, and he found from the logs that the conversion was not happening because the processes were hanging.Archive all old sessions and delete them, if there is an error then let the code clean it up.

  13. dajiaohuang commented on Oct 7, 2026

    @dajiaohuang

    Thanks for the additional reproductions and the blunt feedback, @fusengine. The 440 completed residents with 0 active and 391 spawn failures is an extreme but consistent manifestation of the residency reclamation issue: completed agents are not being evicted from the resident set even after their turns finish and mailboxes are empty, so fresh spawns hit the generic 'agent thread limit reached' error regardless of actual execution capacity.

    @pomazanbohdan: archiving and deleting old sessions is a valid user-side workaround for sessions that have already accumulated stale residents, though it does not address the root cause in the residency/eviction logic. In my own Windows reproduction earlier this week, sending a follow-up to the stuck 'pending_init' child did release capacity (after which a fresh spawn succeeded), but that workaround is not reliable as fusengine and Alex-R-A have reported cases where even follow-ups or interrupts do not clear the block.

    The core issue remains as The-skomoroh identified in the source ordering: terminal results are delivered to the parent before the child is marked evictable (active_turn cleared and mailbox empty), so a concurrent fresh spawn can fail spuriously, and there is no mechanism to retry eviction or distinguish residency exhaustion from active execution capacity limits.

  14. fusengine commented on Oct 7, 2026

    @fusengine

    multi_agent_v2: no way to release completed subagents — close_agent ships in the binary but is only exposed in v1

    Version: codex-cli 0.160.1 (Homebrew cask) · macOS arm64 · model gpt-6-astra (multi_agent_version: v2)

    Config

    [features]
    multi_agent = true
    
    [features.multi_agent_v2]
    enabled = true
    max_concurrent_threads_per_session = 6

    What happens

    1. A session spawns subagents (analysis phase); all of them reach Completed.
    2. The next spawn_agent fails with agent thread limit reached.
    3. Asked to close the finished subagents, the model correctly answers that it has no tool to close them — only spawn_agent, send_message, wait_agent, list_agents, interrupt_agent are exposed. interrupt_agent does not free the slot.
    4. The only way out is starting a new session, which loses the working context.

    Why this looks like a design gap, not just a bug

    Strings in the 0.160.1 binary show:

    • core/src/tools/handlers/multi_agents/close_agent.rs exists.
    • In the tool-spec planner (core/src/tools/spec_plan.rs), close_agent is grouped with the v1-only set: multi_agent_v1 → send_input, resume_agent, close_agent.
    • The close_agent description itself says: "Completed agents remain open and count toward the concurrency limit until closed."
    • v2 relies on automatic eviction instead (v2 resident eviction task failed, failed to shut down v2 resident thread before unloading).

    So v2 removed the manual release path and depends entirely on eviction. When eviction does not happen (see #39694, #50584, #32353), the session is stuck with no recovery tool, while the code to recover already exists.

    The docs make it worse: the subagents page says "Ask Codex directly to … close completed subagent threads", which is impossible under v2.

    Expected

    Any one of these would fix it:

    1. Expose close_agent (or an equivalent release_agent) in v2 as a fallback when a completed agent is not evicted.
    2. Count only non-evictable agents toward max_concurrent_threads_per_session, and evict synchronously before rejecting a spawn.
    3. Make the error actionable: say which agents hold the slots and why they are not evictable (pending mailbox item, durable sleep, pending_init…).
    4. Fix the docs to match v2 behavior.

    Related

    #39694 (same config: 0 active / 440 done, still blocked) · #50584 (false limit below the configured value) · #32353 (queue-only message pins a completed agent) · #33447 (v2 silently ignores agents.max_threads)

  15. fusengine commented on Oct 7, 2026

    @fusengine

    Root cause found (reproducible) + workaround — thread_spawn_edges rows are never closed in v2

    Follow-up to my comment above. Same setup (codex-cli 0.160.1, multi_agent_v2, max_concurrent_threads_per_session = 6).

    Observation in ~/.codex/state_5.sqlite:

    SELECT status, count(*) FROM thread_spawn_edges GROUP BY status;
    -- open|122   (closed: 0)

    Every subagent ever spawned is still open — including ones from previous days. The stuck session alone had 118 open edges, all Completed from the agent's point of view.

    Per codex-rs/agent-graph-store/src/types.rs, Open means "the child thread is still live or resumable as an open spawned agent". Under v2 nothing ever writes Closed (no close_agent tool; interrupt_agent does not touch the edge), so completed agents keep counting.

    Experiment (both directions):

    1. Codex fully quit → UPDATE thread_spawn_edges SET status='closed' WHERE parent_thread_id='<session>' AND status='open'; (118 rows) → resume the session → spawns work again.
    2. The session spawned 5 agents → exactly 5 open edges = 5 subagent slots (6 incl. root) → the 6th spawn fails with agent thread limit reached, although all 5 are completed and one was interrupted.
      So the limit is driven by open spawn edges, and v2 has no path that closes them.

    Workaround (Codex must be fully quit — app and CLI; back up first):

    cp ~/.codex/state_5.sqlite ~/.codex/state_5.sqlite.bak
    sqlite3 ~/.codex/state_5.sqlite "UPDATE thread_spawn_edges SET status='closed' WHERE status='open';"

    Suggested fix: set the edge to Closed when a v2 child reaches a terminal state (Completed / Errored / Interrupted) or is evicted, and/or expose close_agent in v2.

  16. fusengine commented on Oct 7, 2026

    @fusengine

    Correction + working workaround: open thread_spawn_edges are reloaded on resume

    Correction to my previous comment. I wrote that "the limit is driven by open spawn edges". That is wrong for a running session. Watching ~/.codex/state_5.sqlite live, the same session later reached 9 open edges with 5 subagent slots and kept spawning without error, so v2 does free slots in memory, but it never writes the edge back to closed.

    What the data does support:

    Phase Observation
    Running session v2 evicts completed agents in memory and spawns keep working, except when no resident is evictable (the refusal we hit at 5/5 matches #32353 / this issue).
    Resume Edges are never closed (`open

    Timeline from the session rollout (codex-cli 0.160.1, Codex Desktop, multi_agent_v2, max_concurrent_threads_per_session = 6):

    1. Session stuck with 118 open edges; resuming → agent thread limit reached.
    2. Codex quit → edges set to closed → resume → spawns work (5 agents, then a 6th, 7th… up to 9 open edges, no error).
    3. Codex restarted at 11:34 with 9 open edges left → resumed session → collab tool failed: agent thread limit reached at 11:40 and 11:43.

    So the leak is on the persistence/resume path. The workaround below has unblocked the session every time.

    Workaround (Codex fully quit: app and CLI)

    cp ~/.codex/state_5.sqlite ~/.codex/state_5.sqlite.bak
    sqlite3 ~/.codex/state_5.sqlite \
      "UPDATE thread_spawn_edges SET status='closed' WHERE status='open';"

    Run it before relaunching Codex after any long multi-agent session, not only once you are blocked. It only changes the edge status: thread history is kept. I wrapped it in a small shell function that refuses to run while Codex is open, backs up the DB and prints the restore command.

    Suggested fix

    • Set the edge to Closed when a v2 child reaches a terminal state (Completed / Errored / Interrupted) or is evicted.
    • On resume, do not restore children whose thread is already terminal.
    • Optionally expose close_agent in v2 as a manual fallback (it ships in the binary but is only in the v1 tool set).
  17. nilswx commented on Oct 15, 2026

    @nilswx

    Current-source qualification (rust-v0.162.1, tag commit 7a078f6bb4ce0dc2a81408b334ce52979d92c603)

    The open-edge count alone does not appear to consume the V2 resident cap on this tag. restore_v2_agent_metadata restores child identity/path metadata with registry.reserve_spawn_slot(None) and explicitly does not reopen runtimes (spawn.rs). V2 spawn admission uses the separate V2Residency counter, which restoration does not repopulate (residency.rs, spawn.rs). The reported 0.148 alpha/0.147 behavior therefore still deserves runtime reproduction, but the specific theory that passive open edges alone fill V2 residency is stale for 0.162.1. Restored paths can still reserve names, and loading a child later consumes a normal resident slot.

    I did not run this lifecycle against a live daemon; this is source-only and does not rule out the reported admission/status mismatch or the terminal-result versus active_turn-clear race.

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

    appIssues related to the Codex desktop appbugSomething 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