[BUG] Workflow dispatched 334 subagents after a session-limit error; all failed, 111 findings were silently recorded as "refuted", and the run still reported completed

Status Fixed / completed
Maintainer reply None cached
Activity 1 comment · opened Sep 15, 2026 · closed Sep 15, 2026

Summary

A Workflow run hit a session limit partway through. Instead of stopping, the harness dispatched 334 further subagents into the exhausted limit. Every one of them failed with the same error. The workflow then reported status: "completed", discarded everything the successful agents had produced, and returned an empty result.

Same class as #93874 (189 subagents dispatched after a session-limit error) — that issue is still open with no response. The numbers here are nearly identical, which suggests this is reproducible rather than incidental.

Environment

  • Claude Code CLI on Linux
  • Plan: Max 20x
  • Workflow model: claude-fable-5-1
  • Run: 2026-09-14, 17:31–18:12 CEST (durationMs 2,498,017 = 41.6 min)

What the run did

The script had four phases: 9 independent auditors (Find) → Merge → adversarial verification of each finding by 2–3 refuters (Verify) → Critic. The Verify fan-out is by design and scales with the number of findings; it is not runaway recursion (every agent has spawnDepth: 1, nothing spawned anything).

Measured outcome

Per-phase, from the 344 *.meta.json / *.jsonl files under subagents/workflows/<runId>/, deduplicated by message.id:

| Phase | Agents | Tokens | Result |
|---|---:|---:|---|
| Find | 9 | 47,616,388 | completed |
| Merge | 1 | 404,896 | completed |
| Verify | 333 | 1,868,575 | all failed |
| Critic | 1 | 0 | failed, never ran |
| Total | 344 | 49,889,859 | |

workflowProgress status counts: done: 10, error: 334.

All 334 failures carry the identical message:

You've hit your session limit · resets 8:10pm (Europe/Berlin)

So: the 9 Find agents alone consumed 47.6M tokens — 96% of the run — and exhausted the session limit. The harness then dispatched 334 more agents over the following minutes, all of which died on arrival.

The three defects

1. The harness keeps dispatching after a terminal quota error.
The first session-limit error is terminal for the remainder of the window — it is not a transient 429 worth retrying. 334 agents were nevertheless started into it. There is no per-run agent or token budget that would have stopped this, and no way for the script to learn that the quota was gone.

2. Quota failure is indistinguishable from a real result.
This is the damaging part. The run's result object reads:

| field | value |
|---|---|
| raw findings (from the 9 auditors) | 177 |
| merged | 111 |
| confirmed | 0 |
| refuted | 111 |
| critic | null |

All 111 findings are recorded as refuted. Nothing was actually refuted — every refuter died on the session limit before it could read anything. The script had no way to tell "this finding was attacked and did not survive" from "the agent that was supposed to attack it never ran". The result is that 177 findings produced by 9 agents that did complete were silently discarded as disproven.

This is question 2 of #93874, and it is not theoretical: it produced a confidently wrong audit result.

3. The run reports completed.
status: "completed" with error: 334 in its own progress log and a null final phase. Nothing surfaced to the caller indicated that 97% of the run failed for quota reasons.

Secondary: totalTokens does not match measured consumption

| Source | Tokens |
|---|---:|
| workflow JSON totalTokens | 4,290,905 |
| measured across agent transcripts | 49,889,859 |

The reported figure is approximately input + output + cache_creation (7,960 + 41,988 + 3,899,572 = 3,949,520) and appears not to include cache_read_input_tokens (45,940,339). Whether cache-read counts toward a Claude Code subscription allowance is not documented anywhere I can find — Anthropic support confirmed in writing (conversation 215475948345649) that they could not answer this either. Either way, the number shown to the user does not describe what the run did.

Expected behaviour

  • A session-limit / quota error cancels remaining dispatch for that window instead of launching more agents into it.
  • agent() exposes a distinguishable error contract so a script can tell quota failure from an empty or negative result, rather than silently folding failures into a verdict.
  • A run whose progress log contains 334 errors and a null terminal phase does not report completed.
  • Per-run agent and token budgets that the orchestrator will not cross.
  • The displayed token total describes actual consumption.

Reproduction

R=<project>/workflows/<runId>.json
python3 -c "import json;d=json.load(open('$R'));print(d['agentCount'],d['status'],d['result']['confirmed'],d['result']['critic'])"
# count failures by phase
grep -o "\[[a-z]*:[^]]*\] failed: You've hit your session limit" "$R" | wc -l
# true consumption: sum input+output+cache_creation+cache_read over
# <project>/subagents/workflows/<runId>/*.jsonl, dedup by message.id

Related

#93874 — same failure, 189 subagents dispatched after a session-limit error, open, no response.
Adjacent: #64328, #72672, #76970, #68619, #75314, #87178.

---

Edit history: this issue was first filed with the agent count framed as unbounded fan-out and an under-reporting counter as the headline. That framing was wrong — the Verify fan-out is by design and spawnDepth is 1 throughout. Re-measuring the per-phase data showed the actual defect is the post-quota dispatch and the silent conversion of 334 quota failures into 111 "refuted" verdicts. The issue has been rewritten accordingly.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗