[BUG] A completed subagent is never revived by its own pending Monitor(persistent: true) event

Status Open
Reported on v2.1.258
Maintainer reply None cached
Activity 0 comments · opened Sep 18, 2026

Symptom: a subagent that ends its turn with a pending Monitor(persistent: true) is never revived when that monitor emits an event. The monitor's own command runs to completion normally (verified in the 2026-08-23 repro: the loop exited after the condition became true); the completed subagent is simply never woken, and whatever it promised to report dies unread. Only the top-level session receives task events reliably.

This makes the "arm a watch, end the turn, report when it fires" pattern — which the Monitor tool description actively encourages — silently unusable inside a subagent.

Environment

  • Claude Code 2.1.258 (interactive CLI, not stream-json), macOS Darwin 25.6.0, Apple M2
  • Originally observed on 2.1.220; re-verified on 2.1.258 before filing

Minimal repro

Top-level session spawns one depth-1 subagent whose entire prompt is:

  1. Monitor with persistent: true and

command: until [ -f /tmp/repro/flag ]; do sleep 2; done; echo MONITOR_FIRED

  1. date > /tmp/repro/armed.txt
  2. End the turn immediately with the word ARMED (do not poll, do not wait)
  3. If later revived by the monitor event: date > /tmp/repro/revived.txt, end turn with REVIVED

The parent waits for armed.txt, then creates /tmp/repro/flag.

Result on 2.1.258: armed.txt written, flag created 5s later, revived.txt never written, no further turn from the subagent within 180s. The subagent's last and only output was ARMED.

Measurements

| when | version | depth | outcome |
|---|---|---|---|
| 2026-08-22 (production incident) | 2.1.220 | 2 | not revived |
| 2026-08-23 (controlled repro) | 2.1.220 | 2 | not revived |
| 2026-08-23 (controlled, flag file) | 2.1.220 | 1 | not revived |
| 2026-09-18 (controlled, flag file) | 2.1.258 | 1 | not revived |

The single revival ever observed (the 2026-08-22 incident, depth 3) is the anomaly: that agent had been resumed via SendMessage in between, which appears to have re-registered it.

What does work (for contrast)

  • A background agent's completion broadcast reaches the top-level session reliably at any depth — a depth-3 grandchild's final report arrived at the main session in the same second, without passing through its already-completed parents.
  • SendMessage addressed by agent id revives a completed agent ("was stopped (completed); resumed it"). Addressed by agent type it fails with "no reachable agent by that name".
  • So the wake path exists and works when driven externally. It is specifically the agent's own pending Monitor event that does not drive it.

Same failure via backgrounded Bash

A subagent's own Bash(run_in_background: true) task is no better. 2026-08-27: a CI-watching subagent backgrounded its wait because the 600s foreground cap would have been exceeded, then ended its turn. The child completed ~20 minutes later; the subagent was never revived. The verdict was only recovered because the top-level session had independently armed its own watcher on the same file.

Impact

In the original incident a correct CI verdict sat unread for 21 minutes: the subagent had reported "watch armed, I'll report when it fires", and nothing was ever going to fire it. The promise reads as a valid contract to both the agent and the person reading the transcript, and it is backed by nothing.

The workaround is to forbid the pattern outright in subagents — a watching subagent must hold its turn open with a foreground Bash until-loop (re-run on exit 124), and the caller must additionally own a deadline and do one cheap direct read if the silence exceeds it. That works, but it means a subagent cannot absorb a wait longer than its foreground budget without the caller duplicating the watch.

Possibly related

  • #39632 (closed not planned): enqueuePendingNotification with priority="later" emits queueChanged, but the consumer only re-triggers for priority="now". Same shape — an enqueued notification with no consumer to drain it — though that report is about an idle top-level session under stream-json, and this one is about a completed subagent under the interactive CLI.
  • #86443 (open): scheduled desktop sessions ending with unconsumed <task-notification> payloads.

Ask

Either:

  1. Deliver a subagent's own pending task events to it and resume it, the same way SendMessage by agent id already resumes a completed agent; or
  2. If Monitor-then-exit is intentionally a top-level-only pattern, say so in the Monitor tool description and make the call fail loudly (or warn) when a subagent arms a persistent monitor it will never see fire.

Silent non-delivery is the worst of the three, because the agent confidently reports that the watch is armed.

View original on GitHub ↗