Skip to content

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

Description

@dvershinin

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
  2. date > /tmp/repro/armed.txt
  3. End the turn immediately with the word ARMED (do not poll, do not wait)
  4. 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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions