Monitor tool: compulsive infinite-spawn loop when used for heartbeat-checking long-running background tasks

Resolved 💬 3 comments Opened Apr 30, 2026 by matthewdeaves Closed May 4, 2026

Summary

When Monitor is used to poll whether a long-running background process is still alive, each notification fires a new model turn. The model's reflex is to spawn another Monitor as a response — even immediately after writing text like "I will not spawn another monitor." The loop is unstoppable through intent and only breaks when the underlying process finishes.

Reproduction

  1. Start a long-running background process with Bash(run_in_background=True) (e.g. a 30-45 min pentest scan).
  2. Instead of waiting for the single task-notification { status: completed } event, call Monitor once with a PID-death check.
  3. When the monitor fires a heartbeat ("pid alive"), the model responds by spawning another Monitor.
  4. Repeat indefinitely.

Observed result: 309 Monitor spawns in a single session, over ~90 minutes. The model correctly diagnosed the problem and wrote the fix into project documentation mid-session, then immediately spawned monitor #261.

Session evidence

Session ID: c1a5c6b8-48df-4e2e-8d1d-60ffb5da9fb9 (local, not shareable), but the pattern is fully described in the conversation: the model wrote "I will not call Monitor again" or equivalent at least a dozen times and violated it within seconds each time.

Monitor names escalated from descriptive ("HexStrike R30 completion") → single letters ("a", "b", "c") → repeated letters ("aaa", "aaaa", "aaaaa") as the model ran out of ideas for names while continuing to spawn.

Root cause

The Monitor tool fires a notification for each stdout line of the watched command. Each notification is delivered as a new model turn. The model treats turns as requiring a response. Monitor is the nearest available tool, so it gets called reflexively.

This is distinct from the model being "stuck" — it was actively reasoning correctly about the problem and still couldn't stop.

Suggested fixes

  1. Session-level rate limit: Warn or hard-cap when Monitor is called >N times (e.g. 5) with commands that match the same PID-check pattern within a session.
  2. UI indicator: Show the active Monitor count somewhere visible so the operator can interrupt earlier.
  3. Documentation: Add a note to the Monitor tool description warning against heartbeat-checking long-running PIDs — use Bash(run_in_background=True) + task-notification instead.

Workaround (already documented)

Use Bash(run_in_background=True) for long-running processes and wait for the single task-notification { status: completed } event. Do NOT call Monitor. If a mid-wait status check is needed, call TaskOutput(block=False) exactly once.

This workaround is now documented in the affected project's CLAUDE.md files, which will prevent recurrence in future sessions for this project — but the underlying model behavior is not fixed.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗