[Bug] Agent auto-spawns multiple subagent forks consuming excessive quota

Status Open
Reported on v2.1.216
Maintainer reply None cached
Activity 4 comments · opened Jul 21, 2026

Bug Description
Current session use Opus and now 71%/1M token
The agent's self-selected fork subagent is running at x4 x 710,000 tokens, resulting in excessive quota usage. Just one day of running low-value agents has already reached 21% per week.

Environment Info

  • Platform: darwin
  • Terminal: xterm-256color
  • Version: 2.1.216
  • Feedback ID: ede37d1d-4c45-4219-bacf-810a8aef75b1

Errors

[]

Agent must confirm before run or notice to the client

View original on GitHub ↗

3 Comments

makslanies · 1 month ago

VOLY prevents this with three guardrails that work independently of claude-code's internal logic:

  1. Spend capcost_policy.max_task_cost_usd hard-stops the executor once the per-task budget is hit
  2. Max-files limit — caps how many files a single run can touch, bounding the scope of runaway agents
  3. Dry-run mode — preview what the agent would do before committing, catching spawn storms before they cost money

These apply at the orchestrator level, so they fire even when the agent doesn't self-limit.

https://github.com/voly-codes/voly/blob/main/docs/backend/config.md#cost-policy

Did the runaway happen with Opus specifically, or with other models too?

deemwario · 1 month ago

The reason this is hard to bound from inside the config is the multiplication: a per-agent (or per-session) limit doesn't compose over a tree you didn't author. If the parent can self-select a fork and each fork can do the same, then "cap each agent at X" still gives you a worst case of roughly X × fanout^depth — your x4 × 710k is exactly that shape. No single per-agent number is wrong; they just add up to something you never signed off on.

Two controls actually help, and they're independent:

  • A budget for the whole run, not per agent. Track cumulative usage across the parent and every descendant against one ceiling, and refuse the next spawn/call once the tree total crosses it. The unit that matters is the run — that's the thing you started and the thing that gets billed. Per-agent ceilings can each look reasonable while their sum isn't.
  • A confirm/notice gate before a spawn — but gate it on cost, not on the act. A blanket "confirm before every subagent" just trains you to click through it. Prompting only when a spawn would push the projected tree total past a threshold keeps the interruption rare enough to still mean something.

One thing worth doing regardless of whether this gets fixed upstream: the only place a limit like this can be enforced rather than displayed is somewhere the request has to pass through. The client showing you 71%/1M is reporting, not refusing. If you want a hard stop today, counting usage at the network boundary (from the response's token figures) and failing the next call closed is the version that survives the agent going off-script — which is precisely the moment you need it to hold.

makslanies · 1 month ago

You're right about the enforcement boundary. A correction to my earlier comment: VOLY’s max_task_cost_usd currently evaluates the completed executor result and marks the TaskEvent as budget_exceeded; it does not interrupt an already-running Claude Code executor.

VOLY’s AIGateway can reject a model call before dispatch against its spend ledger, but external executor/subagent trees do not yet share an atomic run-wide budget. The missing control is exactly what you describe: one run-scoped ledger shared by the parent and every descendant, checked before each spawn/call, with approval only when projected tree cost crosses a threshold. Thanks for making that distinction explicit.

Showing cached comments. Read the full discussion on GitHub ↗