Agent teams: teammate never exits on shutdown_request; pane never closed (killPane never called) — v2.1.185

Open 💬 2 comments Opened Jun 21, 2026 by romacv

What happened

With agent teams enabled (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1) and split-pane mode, a teammate does not terminate when the lead sends a shutdown request. The teammate acknowledges it ("Acknowledged. Exiting.") but stays at an idle prompt and keeps emitting idle pings. Its split pane is never closed and the underlying claude --agent-id … process keeps running indefinitely. Over a long / autonomous run, orphaned teammate processes and panes accumulate (observed 8–9h-old idle teammates piling up).

Reproduces identically on both split-pane backends — iTerm2 (it2) and tmux — so the defect is backend-independent. Instrumenting the pane layer shows the lead never issues any pane-close command, because it only closes a pane after receiving a shutdown approval message from the teammate, and the teammate never sends one.

Environment

  • Claude Code v2.1.185 (pane/shutdown machinery is byte-identical across 2.1.179–2.1.185)
  • macOS 15 (Darwin 25.6.0), Apple Silicon
  • teammateMode: "tmux" — tested in both resulting backends:
  • iTerm2 backend (terminal = iTerm.app, not inside tmux)
  • tmux backend (inside a tmux -CC session)

Repro

  1. Enable agent teams, teammateMode: "tmux", run claude.
  2. "Spawn a teammate named Probe using model haiku to run echo hi and report done." → a split pane opens, Probe runs, reports idle.
  3. "Ask Probe to shut down."

Expected

Probe exits gracefully and its split pane closes.

Actual (same on iTerm2 and tmux)

  • Probe shows the Shutdown request from team-lead card, replies "Acknowledged. Exiting." / "Exiting." — but the process does not exit and the pane stays open.
  • Lead retries shutdown (plain text ×2, then a structured shutdown_request); Probe keeps replying with idle pings.
  • Lead's hard-stop fallback fails: Stop Task → Error: No task found with ID: Probe@session-…, TaskList empty. The teammate is a team member (mailbox + pane) but is not registered as a task, so there is no working force-terminate by id.
  • SIGTERM to the orphaned process is ignored; only SIGKILL works.

Evidence — instrumented runs

Transparent passthrough shims on it2/tmux logged every invocation.

iTerm2 backend — the only pane commands for the whole spawn→shutdown lifecycle:

it2 session list                                   EXIT=0
it2 session split -v -s <leader-guid>              EXIT=0   # create Probe pane
it2 session send/run -s <probe-guid> … --agent-id Probe@session-…   EXIT=0

tmux backend — the only pane commands:

[TmuxBackend] Created teammate pane for Probe: %1
tmux split-window -d -t %0 -h -l 70% -P -F #{pane_id} -- cat     EXIT=0
tmux set-option -p -t %1 remain-on-exit failed                  EXIT=0
tmux respawn-pane -k -t %1 -- … --agent-id Probe@session-… --model haiku   EXIT=0

→ In both backends: pane creation works perfectly, and no close command is ever issued — no it2 session close, no tmux kill-pane / kill-window / break-pane.

Internal debug log (~/.claude/debug/<session>.txt), both backends:

[ITermBackend|TmuxBackend] Created teammate pane for Probe …
[InboxPoller] Found 1 unread message(s) → Session idle, submitting immediately   (×N — Probe's idle pings)
# grep "shutdown approval" = 0   ;   grep "killPane"/"Killed pane" = 0

Likely root cause

The lead's InboxPoller calls killPane(paneId, backendType) only when it receives a shutdown-_approval_ message carrying paneId + backendType ([InboxPoller] Found N shutdown approval(s)). That count is 0: the teammate acknowledges shutdown in model text but never emits the approval/exit handshake, so:

  1. lead receives 0 approvals →
  2. killPane is never called →
  3. it2 session close / tmux kill-pane is never issued →
  4. pane + process live forever.

On the tmux backend the pane is created with remain-on-exit failed, so a clean teammate exit would auto-close the pane even without kill-pane — but the teammate never exits, so it stays. (And killing the process with SIGKILL leaves a non-zero exit, which remain-on-exit failed keeps open; on iTerm2 the dead process leaves a zombie pane too.)

Secondary: teammates spawned as plain general-purpose agents are registered as team members but not as tasks, so TaskStop/TaskOutput by name@session return "No task found with ID" — the force-terminate fallback can't reach them.

Impact

Long-running and autonomous (/loop) team sessions leak teammate processes and panes that cannot be closed from within the product; recovery requires kill -9 (and manually closing panes on iTerm2). The graceful-shutdown UX ("ask X to shut down") silently does nothing.

Suggestions

  • Make shutdown_request trigger the runtime-level approval+exit on the teammate side regardless of agent type / model, instead of depending on the model emitting an approval.
  • Have the lead killPane on a shutdown timeout even without an approval (fallback after N seconds idle post-request).
  • Register every teammate in the task system (or make force-terminate resolve by member id) so there is a working hard-stop.
  • Close the pane when the teammate process exits, so a dead teammate doesn't leave a zombie pane.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗