Dynamic Workflow: ordering agent doesn't self-detect/abort a runaway subagent fan-out (218 spawned vs ~10 intended)

Open ๐Ÿ’ฌ 1 comment Opened Jun 17, 2026 by gwpl

๐Ÿค–๐Ÿค๐Ÿง‘ This issue was put together collaboratively by a human user and Claude Code.

Summary. A dynamic Workflow was authored to fan out ~10 worker subagents. A separate input bug (Workflow args JSON array delivered to the script as a JSON-string) miscomputed the fan-out width, and the runtime spawned 218 subagents (each a full Opus context) โ€” burning ~700k tokens before a human noticed the live count and manually killed it. The root-cause trigger is detailed in a companion gist (cross-referenced below); this issue is about the blast radius and, primarily, the missing agent self-monitoring.

The damning part: when the human asked the agent about the spawn count, the agent immediately knew 218 was wrong โ€” the knowledge that "this should be ~10, not 218" was clearly available to it. Yet it did not stop its own runaway workflow, and tokens kept burning until the human intervened.

Type of Behavior Issue

Subagent behaved unexpectedly / ordering agent did not self-monitor a runaway fan-out.

What You Asked Claude to Do

Run a dynamic Workflow expected to split the work into ~10 worker subagents.

What Claude Actually Did

  1. Launched the dynamic Workflow.
  2. The fan-out width was miscomputed (stringified args โ†’ String.slice over a JSON string โ†’ N garbage items); see companion gist.
  3. The runtime spawned 218 subagents instead of ~10; ~17 ran to completion on garbage input.
  4. The ordering/main agent did not verify the post-launch spawn count vs intent, did not flag the anomaly, and did not abort.
  5. ~700k tokens burned before a human watching the live progress view manually killed it.

Expected Behavior (the heart of this issue โ€” agent self-monitoring)

  1. Self-verify the launch outcome. After launching a dynamic Workflow, the ordering/main agent should verify post-launch that the spawn count / fan-out width matches intent (here: ~10 expected, 218 actual) and treat a large mismatch as an anomaly.
  2. Abort its own runaway. Given the agent demonstrably had the knowledge that 218 was wrong, there should be an expectation/affordance for it to abort its own runaway workflow before a human has to intervene.
  3. Platform-side guard (complementary). A width-anomaly check that warns/confirms well below the existing 1000-agent hard cap (e.g. a soft ceiling, or relative to the run's rolling fan-out distribution), and/or an author-declarable max fan-out (e.g. parallel(items, { maxWidth: N })) enforced by the runtime โ€” exceeding it errors instead of silently spawning. In headless/cron, hard-fail rather than spawn unless an explicit opt-in is set. Also log() the derived width at t=0 so the count is visible before agent #200.

Key questions for the team

  1. Why doesn't the ordering agent self-verify the launch outcome (agent count / fan-out width vs intent) right after launching?
  2. Given it had the knowledge the spawn was wrong, why is there no expectation/affordance for it to abort its own runaway workflow before the human intervenes?
  3. Can the platform add a width-anomaly check (warn/confirm well below the 1000 hard cap) and/or an author-declarable max fan-out?

Impact

High โ€” ~700k tokens wasted on a single silent runaway; depended entirely on a human watching the live view to stop it.

Reproducible

The args-string trigger is reproducible; the broader point (no self-verify / self-abort of fan-out width) is independent of any single root cause โ€” any miscompute of width has the same silent, expensive outcome today.

Environment

  • Claude Code: 2.1.179
  • Model: Opus 4.8
  • Platform: Linux (Anthropic API)

Related

View original on GitHub โ†—

This issue has 1 comment on GitHub. Read the full discussion on GitHub โ†—