usestrix/strix · warning · SubagentBudgetReservedError

Sub-agent budget reserve reached: spent ${cost:.4f} of ${sel

Error message

Sub-agent budget reserve reached: spent ${cost:.4f} of ${self._max_budget_usd:.2f} (>= {round(_SUBAGENT_BUDGET_RESERVE * 100)}% reserve); stopping this sub-agent so the root agent can finish the scan.

What it means

Raised by the budget hook (strix/core/hooks.py:268) when a non-root (sub-agent) LLM call pushes total scan cost to or past 90% of max_budget_usd (_SUBAGENT_BUDGET_RESERVE = 0.90) while running headless (non-interactive). The last 10% of the budget is reserved so the root agent can still finish, write its report, and shut down cleanly. It subclasses RuntimeError and is caught internally in strix/core/execution.py, where it marks the sub-agent as stopped rather than aborting the whole scan.

Source

Thrown at strix/core/hooks.py:268

        except Exception:
            logger.exception("failed to record SDK usage for agent %s", agent_id)

        if self._max_budget_usd is not None:
            cost = report_state.get_total_llm_cost()
            if cost >= self._max_budget_usd:
                if self._interactive:
                    raise BudgetPausedError(
                        f"Scan budget of ${self._max_budget_usd:.2f} reached "
                        f"(spent ${cost:.4f}); pausing until the user continues"
                    )
                raise BudgetExceededError(
                    f"Token budget of ${self._max_budget_usd:.2f} exceeded (spent ${cost:.4f})"
                )
            is_root = ctx.get("parent_id") is None
            if not self._interactive and not is_root:
                reserve_limit = self._max_budget_usd * _SUBAGENT_BUDGET_RESERVE
                if cost >= reserve_limit:
                    raise SubagentBudgetReservedError(
                        f"Sub-agent budget reserve reached: spent ${cost:.4f} of "
                        f"${self._max_budget_usd:.2f} "
                        f"(>= {round(_SUBAGENT_BUDGET_RESERVE * 100)}% reserve); stopping this "
                        "sub-agent so the root agent can finish the scan."
                    )

View on GitHub (pinned to 8551339130)

Solutions

  1. No action needed for the scan itself: the root agent finishes and still produces a report; check run.json and penetration_test_report.md for coverage.
  2. Increase the ceiling: rerun with a larger --max-budget so sub-agents are not cut off at 90% of it.
  3. Switch to interactive mode (drop -n) — the reserve check is skipped when interactive, and the full budget raises BudgetPausedError instead so the user can continue.
  4. Use a cheaper model (STRIX_LLM / model=) to keep sub-agent spend under the reserve.
  5. Resume the scan (strix resume / is_resume path) with a higher budget to continue where sub-agents stopped.

Example fix

# before
strix -n -t https://example.com --max-budget 2   # sub-agents stop at $1.80

# after
strix -n -t https://example.com --max-budget 10  # reserve is $9.00, sub-agents finish
Defensive patterns

Strategy: try-catch

Validate before calling

from strix.core.hooks import SubagentBudgetReservedError  # subclass of RuntimeError
# Pre-check before spawning more sub-agent work:
spent = report_state.get_total_llm_cost()
if max_budget_usd is not None and spent >= max_budget_usd * 0.90:
    print('sub-agent reserve reached; root agent should wrap up')

Type guard

def is_subagent_budget_reserve(exc: BaseException) -> bool:
    return isinstance(exc, RuntimeError) and 'Sub-agent budget reserve' in str(exc)

Try / catch

try:
    await run_strix_scan(...)
except SubagentBudgetReservedError:
    # non-fatal: root agent still finishes and writes the report
    logging.warning('sub-agents stopped at budget reserve; report still produced')

Prevention

When it happens

Trigger: Running strix headless (-n) with --max-budget N while sub-agents burn tokens; on each SDK response the hook compares report_state.get_total_llm_cost() against max_budget_usd * 0.90 and raises when a sub-agent (ctx parent_id is not None) crosses that reserve threshold.

Common situations: Deep scan modes that fan out many sub-agents; cheap max-budget values (e.g. $1-5) with expensive models; cost spikes from large tool outputs inflating token usage.

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/ee49c7a903b26ddb. Report an issue: GitHub.