usestrix/strix · error · BudgetExceededError

scan budget reached

Error message

scan budget reached

What it means

BudgetExceededError('scan budget reached') raised in `_run_agent` after the first input cycle when `coordinator.budget_stopped` is set: total LLM spend across the scan reached `max_budget_usd`. The agent is marked 'stopped' and the error propagates to terminate the run. (In interactive mode the hook instead raises BudgetPausedError which is suppressed here; this raise fires for the non-interactive/headless path or when the coordinator already recorded a stop.)

Source

Thrown at strix/core/execution.py:202

    event_sink: StreamEventSink | None = None,
    hooks: RunHooks[dict[str, Any]] | None = None,
) -> RunResultBase | None:
    await coordinator.attach_runtime(
        agent_id,
        session=session,
        interrupt_on_message=interactive,
    )
    result: RunResultBase | None = None

    first_cycle_input = await _seed_and_prepare_first_input(
        session, initial_input, start_parked=start_parked
    )

    budget_stopped = coordinator.budget_stopped
    reserve_stopped = coordinator.reserve_stopped
    if budget_stopped:
        await coordinator.set_status(agent_id, "stopped")
        raise BudgetExceededError("scan budget reached")
    if reserve_stopped and context.get("parent_id") is not None:
        await coordinator.set_status(agent_id, "stopped")
        raise SubagentBudgetReservedError("scan reached the sub-agent budget reserve")

    if reserve_stopped and start_parked and interactive and context.get("parent_id") is None:
        await coordinator.send(agent_id, _reserve_notice())

    if not (start_parked and interactive):
        with contextlib.suppress(BudgetPausedError):
            result = await _run_until_lifecycle(
                agent,
                coordinator,
                agent_id,
                initial_input=first_cycle_input,
                run_config=run_config,
                context=context,
                max_turns=max_turns,
                session=session,

View on GitHub (pinned to 8551339130)

Solutions

  1. Re-run with a higher budget: `strix -n -t ./ --max-budget 50`
  2. Use `--scan-mode quick` or narrow the target to reduce cost
  3. For interactive runs, the budget pauses instead of stopping — continue from the TUI after reviewing spend, or use extend_budget semantics
  4. Review the run artifacts (run.json llm_usage.cost) to see where cost went before re-running

Example fix

# before
strix -n -t ./ --scan-mode deep --max-budget 5   # BudgetExceededError: scan budget reached
# after
strix -n -t ./ --scan-mode deep --max-budget 25
Defensive patterns

Strategy: validation

Validate before calling

# size the budget before launching: quick scans of small targets need ~1-5 USD, deep scans often 10-50+
import subprocess, json

def budget_from_previous_run(runs_dir: str, fallback: float = 10.0) -> float:
    # read the last run.json cost and add headroom
    try:
        run = sorted(Path(runs_dir).glob("*/run.json"))[-1]
        cost = json.loads(run.read_text())["llm_usage"]["cost"]
        return max(fallback, cost * 1.5)
    except (OSError, KeyError, IndexError):
        return fallback

Try / catch

from strix.core.exceptions import BudgetExceededError  # module path per repo layout

try:
    run_scan(target="./", scan_mode="quick", max_budget=10)
except BudgetExceededError as e:
    # partial artifacts still written — inspect before re-running with a larger budget
    ...

Prevention

When it happens

Trigger: A headless scan (`strix -n`) with `--max-budget N` where cumulative LLM cost recorded in report_state crosses N during the run; the coordinator's budget_stopped flag is observed after seeding the first input.

Common situations: Deep scan modes on large targets exhausting the budget; long autonomous runs where cost accumulates faster than expected; budget set too low relative to target size (e.g. --max-budget 1 on a deep scan).

Related errors


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