Team shutdown_request acknowledged but teammates never terminate; TeamDelete blocked until session ends
Summary
SendMessage accepts type: "shutdown_request" and returns success + a
request ID, but teammates never terminate. TeamDelete is then
blocked for the life of the session.
Unclear from outside whether shutdown_request is a declared protocol
or forwarded free-form content — the{"success": true, "request_id": "shutdown-<ts>@<name>"} response
suggests first-class handling, but we can't confirm against the tool
schema. Either way, there's currently no way to clean up teams from
within a session.
Filed as a follow-up to the #44971 investigation (now fixed in 2.1.105).
Environment
- Claude Code 2.1.105 (installed 2026-04-13)
- macOS
- Plugin: Coolant —
consumes SubagentStart/SubagentStop hooks
Reproduction
TeamCreate({name: "test-team"})- Spawn 2-4 teammates via
Agent({team_name: "test-team", name: "alpha", ...}) - Let at least one teammate complete a turn so it's idle in mailbox
- Send shutdown:
``json``
SendMessage({
"to": "alpha",
"type": "shutdown_request",
"message": {"type": "shutdown_request", "reason": "..."},
"recipient": "alpha",
"content": "..."
})
- Observe response:
{"success": true, "request_id": "shutdown-<ts>@alpha"} - Observe teammate: wakes (SubagentStart), processes message, goes
idle (SubagentStop), sends idle_notification, does NOT terminate
TeamDelete({name: "test-team"})→ fails with
"Cannot cleanup team with N active members"
What we tried
Three rounds of escalating shutdown attempts across all 4 teammates in
a live test:
Round 1 — Broadcast:
SendMessage({
"to": "*",
"type": "broadcast",
"summary": "Shutdown request",
"message": {"type": "shutdown_request", "reason": "Investigation complete."}
})
Round 2 — Per-teammate with explicit type: "shutdown_request":
SendMessage({
"to": "alpha",
"type": "shutdown_request",
"message": {"type": "shutdown_request", "reason": "Investigation complete."},
"recipient": "alpha",
"content": "Investigation complete."
})
Response: {"success": true, "message": "Shutdown request sent to alpha. Request ID: shutdown-1776305814048@alpha"}
Round 3 — Plain text asking teammates to approve pending request:
SendMessage({
"to": "alpha",
"summary": "Please exit",
"message": "Your work is complete. Please respond to the pending shutdown request by approving it."
})
Evidence
Each teammate's inbox at ~/.claude/teams/<team>/inboxes/<name>.json
shows all messages delivered and marked "read": true. Teammates
received and processed the shutdown requests but did not terminate.
Repeated sequence across all rounds, for each teammate:
- SendMessage delivers shutdown_request → CC returns success + request ID
- SubagentStart fires (teammate wakes)
- Teammate processes message, goes idle
- SubagentStop fires
idle_notificationsent to team lead- Teammate remains alive in team
Question for Anthropic
Is type: "shutdown_request" declared in SendMessage's tool schema as
a recognized type, or is it free-form content that SendMessage happens
to forward to the inbox? The request-ID format in the response
suggests explicit handling, but we can't confirm from the outside.
This determines whether the bug is "protocol exists and is ignored"
or "user tried to invoke a protocol that doesn't exist."
Impact
TeamDeletecannot clean up teams while teammates are alive- No documented way to terminate teammates from inside a session
- Users iterating on team configs must restart the whole CC session
- Stale team state accumulates on disk under
~/.claude/teams/<name>/
Asks
If shutdown_request IS a declared protocol: teammates should honor
it and terminate.
If it ISN'T: TeamDelete needs a force option (or some documented
path to terminate members), because there's currently no way to clean
up teams within a session.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗