close_agent is missing from the VS Code multi-agent tool schema

Open 💬 4 comments Opened Jul 30, 2026 by gcalpay

What version of the IDE extension are you using?

26.721.41059

What subscription do you have?

ChatGPT Plus

Which IDE are you using?

Visual Studio Code 1.131.0 using Remote - WSL

What platform is your computer?

Microsoft Windows NT 10.0.19045.0 x64

What issue are you seeing?

In new Codex chats opened through the VS Code extension, close_agent is missing from the callable collaboration-tool schema even though multi_agent is enabled.

The affected sessions expose:

  • spawn_agent
  • followup_task
  • send_message
  • interrupt_agent
  • list_agents
  • wait_agent

They do not expose close_agent.

This is partial tool exposure: multi-agent support is available, but the operation needed to close a completed subagent is missing. interrupt_agent is not a replacement because it only interrupts the agent's current turn and explicitly leaves the agent available.

The issue persists after updating the extension, completely restarting VS Code, and creating multiple brand-new chats.

What steps can reproduce the bug?

  1. Enable multi-agent support in ~/.codex/config.toml:

[features]
multi_agent = true

  1. Restart VS Code and open a Git repository through Remote - WSL.
  1. Open a new Codex chat and send this exact request:

Use a subagent to list the repository's top-level files. Wait for the subagent to finish, close it using close_agent, and report the lifecycle operations you performed.

  1. Observe that the session can access spawn_agent and wait_agent, but cannot perform the requested cleanup because close_agent is absent from its callable tool schema. The available cleanup-adjacent operation is interrupt_agent, which interrupts the current turn but leaves the agent available.

What is the expected behavior?

With stable multi_agent enabled, every new VS Code Codex chat should receive the complete documented collaboration lifecycle, including a callable close_agent operation.

A workflow should be able to:

  1. spawn a child agent;
  2. wait for its result;
  3. explicitly close the child;
  4. verify that the child reached a terminal state and its slot was reclaimed.

If close_agent has intentionally been replaced, the extension should expose and document an equivalent finalization operation. interrupt_agent should not be treated as equivalent to lifecycle closure.

Additional information

The Codex runtime bundled with the affected extension reports:

codex-cli 0.146.0-alpha.3.1

Relevant configuration:

[features]
multi_agent = true

The VS Code workspace is opened through Remote - WSL with Ubuntu 24.04.4 LTS. The Windows host platform is recorded in the dedicated platform field above.

View original on GitHub ↗

4 Comments

KNaiFen · 23 days ago

codexcli 0.146 macos
no vscode, same bug

wuyak · 18 days ago

I can reproduce the same missing tool surface outside VS Code.

Environment:

  • Codex Desktop 26.803.41515 (build 6321)
  • bundled CLI codex-cli 0.146.0
  • macOS

The collaboration tools exposed in the session are:

  • spawn_agent
  • followup_task
  • send_message
  • interrupt_agent
  • list_agents
  • wait_agent

There is no close_agent. interrupt_agent only ends the current turn and leaves the child thread addressable, so it is not an equivalent close/retire/reclaim operation.

This suggests the gap is not VS Code-specific. It would help to either expose close_agent consistently or document the supported idempotent replacement, with outcomes such as closed, already_closed, still_active, and not_found.

mwcmaniac45 · 16 days ago

Also reproduced in the Codex-native Code-mode collaboration surface on macOS with Codex CLI 0.147.0. The parent can spawn, list, wait for, and interrupt children, but has no close_agent or documented equivalent.

Please expose the actual negotiated lifecycle capability to the parent surface: if native close is supported, provide an idempotent close operation that confirms the parent-child edge is closed; if it is unsupported, return an explicit unsupported/terminal-unclosed state so callers can halt safely rather than silently retaining concurrency. A wait timeout must not authorize closure of a nonterminal child, and archive should remain separate from lifecycle closure.

This is consistent with the tagged V1 source defining close_agent as the operation that releases completed-agent concurrency, while the observed V2-style surface provides no corresponding safe operation.

Geektrovert · 15 days ago

Adding some context from our side, because this has happened enough times that we finally sat down and traced it properly.

During a long multi-agent session in ChatGPT Desktop on macOS, the system ran out of application memory. The Force Quit window showed ChatGPT using 25.86 GB.

!macOS Force Quit dialog showing ChatGPT using 25.86 GB

_This screenshot shows the failure we hit, but it does not prove what caused all 25.86 GB of memory use._

This was not a one-off for us. We have lost work or had to stop and clean up the machine several times after long multi-agent sessions. I cannot say that every incident had exactly the same cause, but the pattern has been consistent enough—and disruptive enough—that we wanted to understand what was actually being left behind.

During the cleanup that led to this investigation, we recovered roughly 3.5 GB of disk space from agent-related processes and build state. That was a separate storage problem, but it prompted us to look more closely at the lifecycle of completed subagents.

One part of the problem was straightforward to reproduce:

  • after two V2 subagents completed, the root and both child MCP processes were still running and using roughly 215 MiB of combined MCP RSS;
  • calling interrupt_agent did not reclaim them, which is consistent with what that operation promises to do;
  • explicitly unloading the completed children left only the root MCP process, at roughly 71.7 MiB;
  • across three runs, tracked RSS dropped by about 140–143 MiB each time.

I do not think this explains the whole 25.86 GB incident. The root process continued to grow during the probe, so there is clearly more going on. What it does show is that completed subagents can retain a meaningful amount of memory and their MCP processes indefinitely, and that this portion can be reclaimed reliably.

I put together a local prototype of a resumable release_agent operation. It only releases completed or interrupted agents that have no active work or pending messages. It shuts down the resident session and MCP processes but keeps the agent’s identity and history, so a later followup_task can reload the same agent instead of creating a new one.

The current prototype is available here:

https://github.com/Geektrovert/codex/tree/fix/subagent-session-release

It is rebased onto the current main as of commit 6b18f03bc0311ddd6069cdefb79251cdafcdc1a3. The rebased tree compiles, and its formatting and diff checks pass. I could not complete the focused test run because the cold Cargo build filled the remaining disk space. I cleared only the generated build cache afterward.

I also found the earlier work around automatic idle-thread shutdown and race-safe teardown, including #31304, as well as the more recent lazy MCP startup work in #38217. The former was closed without merging, and the latter reduces startup cost but does not unload completed agents, so I am not sure which lifecycle direction the team currently prefers.

Before taking the prototype further, I would really appreciate a steer from the maintainers: does an explicit, resumable release_agent sound like the right direction, or would you rather solve this through automatic idle cleanup or by permanently closing the parent-child relationship?

There are still two concurrency edge cases I want to tighten up, and I need to complete the focused tests once there is enough build space. If this approach fits what the team has in mind, I would be happy to finish that work and open a PR if you would like me to.