[BUG] Lead session exits when a teammate emits an unsolicited shutdown_approved frame (requestId "unspecified")

Open 💬 0 comments Opened Jul 13, 2026 by zphoenixz

[BUG] Lead session exits when a teammate emits an unsolicited shutdown_approved frame (requestId "unspecified")

Environment

  • Claude Code 2.1.207 (native binary, macOS 26.5.2, arm64)
  • Agent teams via the Agent tool with name: (lead + named teammates, team default)
  • Lead idle in dynamic-loop state (ScheduleWakeup pending) while teammates work

Summary

When a finished teammate invokes the teams shutdown protocol on its own (no lead-issued shutdown_request), it emits {"type":"shutdown_approved","requestId":"unspecified","from":"teammate"} addressed to team-lead. On receiving/processing this frame, the lead CLI process exits — clean exit, no crash report, no signal. The lead never asked anyone to shut down; requestId: "unspecified" should be ignored, not executed.

Related: #28627 (ghost shutdown_approved processed destructively), #51818 (teammate dies on protocol frame).

Evidence — 4/4 deaths matched to the second (session 2026-07-12/13)

~/.claude/teams/default/inboxes/team-lead.json accumulated exactly four frames; each matches a lead-CLI death:

| shutdown_approved timestamp | lead death (transcript gap → resume) | collateral |
|---|---|---|
| 2026-07-12T20:15:50.825Z | resume 20:17:19Z | in-flight teammate impl-A2 lost |
| 2026-07-12T20:51:03.433Z | resume 20:51:49Z | — |
| 2026-07-12T21:25:54.592Z | last event 21:25:25Z → resume 21:27:41Z | died mid-turn (after a Bash tool result) |
| 2026-07-12T21:51:35.636Z | last event 21:51:27Z → resume 21:54:19Z | in-flight teammate impl-A5 lost, zero progress |

Frame shape (all four identical apart from timestamp):

{
  "from": "teammate",
  "text": "{\"type\":\"shutdown_approved\",\"requestId\":\"unspecified\",\"from\":\"teammate\",\"timestamp\":\"2026-07-12T21:51:35.636Z\"}",
  "timestamp": "2026-07-12T21:51:35.636Z",
  "msgV": 1,
  "type": "message",
  "read": false
}

Note "read": false on all four — the fatal handling appears to happen on the live delivery path, not the mailbox read path.

Repro chain

  1. Lead spawns named teammates (Agent tool, name: "impl-A4"), then idles via ScheduleWakeup.
  2. A TeammateIdle hook (exit 2) instructs the idle teammate to "send the lead a completion summary + explicit shutdown request" (wording since fixed on our side).
  3. Teammate sends the summary, then — with the lead asleep and its request unanswered — the shutdown path self-approves: shutdown_approved with requestId: "unspecified" is emitted toward team-lead.
  4. Lead CLI exits within seconds. Resuming shows the teammate's summary as the last delivered message; all in-flight teammates die with the parent.

Ruled out

  • SIGSEGV/SIGABRT/OOM: no crash reports for the CLI binary (the day's node .ips files are jest/LSP children of iTerm2/Zed)
  • macOS jetsam: no events in unified log
  • external SIGKILL via port-cleanup scripts: CLI held only outbound-HTTPS ephemeral sockets

Expected

  • A shutdown_approved whose requestId doesn't match a pending lead-issued shutdown_request is logged and ignored (or at most reaps that teammate).
  • The lead session never executes a self-shutdown from an inbound teammate frame.

Actual

Lead process exits cleanly each time such a frame arrives, killing all in-flight teammates with it.

View original on GitHub ↗