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

  1. Raise GENERATION_MAX_COST_USD in backend/.env or config if the workload legitimately costs more.
  2. Switch to a cheaper model or reduce the number of variants running concurrently (cost is per-variant).
  3. Inspect the [BUDGET] console log line to see actual spend vs cap before changing anything.
  4. 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

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


AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14). Data as JSON: /api/errors/e66c4185dd644fd1. Report an issue: GitHub.