[BUG] Agent teams: Monitor events and background-task notifications never wake an idle teammate — dropped, not queued (only SendMessage wakes it)

Open 💬 0 comments Opened Jul 13, 2026 by genesiscz

[BUG] Agent teams: Monitor events and background-task notifications never wake an idle teammate — dropped, not queued (only SendMessage wakes it)

Environment

  • Claude Code version: 2.1.206
  • OS: macOS (darwin 25.3.0)
  • Mode: interactive REPL, agent teams; teammates spawned via the Agent tool (named, background)
  • Models: main session on claude-fable-5; teammates on haiku / sonnet (reproduces on both)

Summary

A teammate/subagent that has ended its turn (idle) is never re-invoked by:

  1. Monitor tool events firing on a background Bash task's stdout it armed earlier, nor
  2. completion notifications of its own background Bash tasks (run_in_background: true process exiting).

The pending notification is also not injected when the teammate is later woken by a SendMessage — transcript inspection shows the Monitor event never enters the subagent's transcript at all while idle or at wake; at best it trickles in mid-turn after the agent is already active again (observed arriving only after the awake agent had manually tail'd the watched file). The only channel that wakes an idle teammate is a harness-native SendMessage.

The main session is not affected — its Monitor events re-invoke it between turns, as documented. The asymmetry is teammates/subagents only.

Practical impact: any teammate that relies on a Monitor-watched stream (inter-agent messaging, log watchers, dev-server supervision) silently stops processing the moment it idles. It looks alive (its background process keeps running and consuming) but reacts to nothing until a human or the lead notices the silence and pings it over SendMessage. In a real multi-agent session this produced repeated multi-ten-minute coordination gaps.

Reproduction

Setup: any long-running background process that emits lines on stdout. Ours was a file-tailing message CLI; a tail -f on a growing file should do.

  1. Main session spawns a named teammate via the Agent tool with these instructions:
  • Start the long-running emitter via Bash run_in_background: true (stdout only).
  • Arm Monitor on that shell's stdout.
  • Confirm readiness via SendMessage, then end the turn (idle; no polling).
  • On any wake: report exactly what woke it and whether the watched line was already in context.
  1. While the teammate is idle, cause a new line to appear on the watched stdout (we sent a message through the CLI; provable delivery — the line lands in the background task's output file on disk within ~1s).
  2. Wait. Nothing happens — we observed a 95s controlled gap and, in the wild, gaps of tens of minutes. The teammate transcript gains zero entries in this window.
  3. Send the teammate a SendMessage. It wakes immediately. Its wake context contains only the SendMessage (+ housekeeping attachments) — no Monitor event, no watched-line content.
  4. The teammate finds the line only by manually reading the task output file. In one run, its own Monitor then fired a late task-notification for that same line — after the manual read, mid-turn.

Variant: replace the stream+Monitor with a background process that exits when the line arrives (completion-notification path). Same result: process exited cleanly with the line printed while the teammate was idle; no wake (teammate confirmed: "task completion did not wake me; the content was not in my context — the task-notification system reminder appeared AFTER your teammate message woke me").

Timeline from a controlled run (UTC, 2026-07-13)

20:52:47  teammate arms Monitor on background stream       (tool_use OK in transcript)
20:52:55  teammate ends turn -> idle
20:53:04  new line emitted on watched stdout               (on disk at 20:53:05, verified)
          ... 95s: teammate transcript = ZERO entries ...
20:55:00  lead sends SendMessage nudge                     -> teammate wakes instantly
          wake bundle: nudge + deferred-tools delta + skill listing. NO monitor event.
20:55:07  teammate manually tails the output file          -> finds the line
20:55:1x  teammate's own Monitor fires a LATE notification for that same line (post-read)

Subagent transcript (~/.claude/projects/<project>/<session>/subagents/agent-<name>-*.jsonl) confirms: between the idle boundary and the SendMessage there are no entries of any type.

Expected behavior

Either of:

  • Monitor events / background-task completions re-invoke an idle teammate the same way they re-invoke the main session (preferred), or
  • at minimum, pending Monitor/task notifications are injected into the teammate's context when it is next woken, instead of being dropped.

Prior art / related issues

  • #39632 (closed, stale) — same mechanism class root-caused for headless main sessions: notification enqueued after the idle-poll loop exited; queueChanged emission only re-triggers run() for priority="now". The REPL main session is immune because its store drains every emission. Our report is the teammate-scoped sibling of this race, still live on 2.1.206.
  • #76681 (open) — background-task notification enqueued but never delivered when the owning subagent already completed; closest analog for the task-exit variant.
  • #69732, #69621, #66219 — same notification/teammate-lifecycle subsystem (misrouting, under-documentation, over-delivery).
  • Changelog 2.1.183 "Fixed background tasks started by a teammate being killed when the teammate finishes a turn" — adjacent fix in the same subsystem; the wake side is still missing.

Workaround

Dual-channel protocol: keep payloads on a durable channel (file/cursor-based), and pair every send to a possibly-idle teammate with a SendMessage nudge; the woken teammate must actively drain the watched file because the missed notifications are never replayed. Works, but costs an orchestration round-trip per message and only helps senders who know the recipient might be idle.

View original on GitHub ↗