usestrix/strix · warning · SubagentBudgetReservedError
scan reached the sub-agent budget reserve
Error message
scan reached the sub-agent budget reserve
What it means
SubagentBudgetReservedError raised when a child agent (context.parent_id is not None) is halted because total spend reached the sub-agent reserve threshold (a fraction of max_budget_usd, _SUBAGENT_BUDGET_RESERVE). The reserve exists so children can't consume the whole budget and starve the root agent, which needs headroom to finish and write the report. The child is marked 'stopped' and the error terminates that child's run.
Source
Thrown at strix/core/execution.py:205
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,
interactive=interactive,
event_sink=event_sink,
hooks=hooks,View on GitHub (pinned to 8551339130)
Solutions
- Increase --max-budget so the reserve threshold leaves children enough room
- Configure cheaper models for sub-agents (model routing config) to slow cost growth
- Reduce scan breadth (quick mode, fewer sub-agents) so the root finishes within the reserve
- Treat as partial: the root agent may still complete the scan with what it has; check the report before re-running
Defensive patterns
Strategy: validation
Validate before calling
# keep sub-agent model cost low so children stay under the reserve line SUBAGENT_MODEL = "openai/gpt-4o-mini" # cheap ROOT_MODEL = "openai/gpt-5.4" # strong # budget must cover children up to reserve AND the root's finish assert max_budget > expected_child_spend / _SUBAGENT_BUDGET_RESERVE
Try / catch
from strix.core.exceptions import SubagentBudgetReservedError
try:
await run_child_agent(...)
except SubagentBudgetReservedError:
# designed stop, not a crash: parent still has reserve to finish
log("child stopped at reserve; root continues") Prevention
- Budget so that max_budget * reserve fraction exceeds expected total child spend
- Cap the number of concurrent sub-agents in scan config
- Catch SubagentBudgetReservedError where children are spawned and treat it as a normal completion signal
When it happens
Trigger: Non-interactive scans with sub-agents: cost crosses `max_budget_usd * _SUBAGENT_BUDGET_RESERVE` while a spawned agent is running; the child observes coordinator.reserve_stopped at the first-cycle checkpoint and raises.
Common situations: Sub-agent-heavy scans (deep mode spawning many specialists) where children burn budget early; budget set tight so the reserve line is crossed quickly; an expensive model configured for sub-agents.
Related errors
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/231b45e70335509f.
Report an issue: GitHub.