abi/screenshot-to-code · error · BudgetExceededError
Generation stopped: this variant exceeded its resource limit
Error message
Generation stopped: this variant exceeded its resource limit.
What it means
BudgetExceededError is raised by the agent engine's tool loop when the accumulated session cost (session.total_cost_usd()) exceeds GENERATION_MAX_COST_USD from backend config. It is checked only when the run would otherwise continue (tool calls pending), so a final answer is never aborted mid-stream; unpriced models return None and are never bounded. The frontend renders it as 'Generation stopped: this variant exceeded its resource limit.'
Source
Thrown at backend/agent/engine.py:276
started_tool_ids,
streamed_lengths,
)
turn = await session.stream_turn(on_event)
if not turn.tool_calls:
return await self._finalize_response(turn.assistant_text)
# Abort only when the run would otherwise continue: a run that
# just produced its final answer is already paid for. Unpriced
# models return None and are not bounded.
spent = session.total_cost_usd()
if spent is not None and spent > GENERATION_MAX_COST_USD:
print(
f"[BUDGET] Aborting variant {self.variant_index}: "
f"${spent:.2f} > ${GENERATION_MAX_COST_USD:.2f}"
)
raise BudgetExceededError()
executed_tool_calls: List[ExecutedToolCall] = []
for tool_call in turn.tool_calls:
tool_event_id = tool_call.id or self._next_event_id("tool")
if tool_event_id not in started_tool_ids:
await self._send(
"toolStart",
data={
"name": tool_call.name,
"input": summarize_tool_input(tool_call, self.file_state),
},
event_id=tool_event_id,
)
if tool_call.name == "create_file":
content = extract_content_from_args(tool_call.arguments)
if content:
await self._stream_code_preview(tool_event_id, content)View on GitHub (pinned to d026163f58)
Solutions
- Raise GENERATION_MAX_COST_USD in backend/.env or config if the workload legitimately costs more.
- Switch to a cheaper model or reduce the number of variants running concurrently (cost is per-variant).
- Inspect the [BUDGET] console log line to see actual spend vs cap before changing anything.
- If the run should degrade gracefully, catch BudgetExceededError in the caller and return the best partial assistant_text seen so far.
Example fix
# before GENERATION_MAX_COST_USD=1.0 # after (backend/.env) GENERATION_MAX_COST_USD=5.0
Defensive patterns
Strategy: validation
Validate before calling
from backend.config import GENERATION_MAX_COST_USD
# before starting an expensive variant, estimate feasibility
if session.total_cost_usd() is not None and session.total_cost_usd() >= GENERATION_MAX_COST_USD:
raise BudgetExceededError() Try / catch
try:
result = await engine.run(model, messages)
except BudgetExceededError:
# surface a friendly message, keep partial output if any
await send("status", data={"message": "Budget exceeded for this variant"}) Prevention
- Size GENERATION_MAX_COST_USD to model pricing x expected turns before starting a batch.
- Watch for [BUDGET] console lines during long runs and adjust or abort early.
- Prefer cheaper models for exploratory variants; reserve expensive ones for finals.
When it happens
Trigger: A long multi-turn agent run (up to 30 tool-loop steps) whose cumulative token cost crosses the configured GENERATION_MAX_COST_USD cap before producing a final assistant answer without tool calls.
Common situations: GENERATION_MAX_COST_USD set very low for the model being used, expensive models (e.g. high-tier Claude/GPT) doing many image-generation tool calls, or a task that genuinely needs more turns than the budget allows.
Related errors
- Agent exceeded max tool turns
- Generation finished without producing any output.
- OpenAI API key is missing.
- Anthropic API key is missing.
- Gemini API key is missing.
AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14).
Data as JSON: /api/errors/e66c4185dd644fd1.
Report an issue: GitHub.