shareAI-lab/learn-claude-code · error · WorkflowInputError

token budget exceeded ({self._spent + n} > {self._total})

Error message

token budget exceeded ({self._spent + n} > {self._total})

What it means

Budget.add raises WorkflowInputError when adding n tokens would push spent above total. The budget exists so runaway workflows fail loudly at the next agent() call instead of silently overspending; the message shows the exact arithmetic (spent + n > total). With total=None the budget is unlimited and this error cannot fire.

Source

Thrown at s16_workflow_runtime/code.py:381

        self._f.flush()
        self.cache[key] = value

    def close(self):
        self._f.close()


# -- Token Budget --
class Budget:
    """budget.total / spent() / remaining(). Once spent reaches total, agent()
    calls raise instead of silently overspending."""

    def __init__(self, total=None):
        self.total = total
        self._spent = 0

    def add(self, n):
        if self.total is not None and self._spent + n > self.total:
            raise WorkflowInputError(
                f"token budget exceeded ({self._spent + n} > {self.total})"
            )
        self._spent += n

    def spent(self):
        return self._spent

    def remaining(self):
        return float("inf") if self.total is None else max(0, self.total - self._spent)


# -- Workflow Task Lifecycle --
class LocalWorkflowTask:
    """Hold workflow status, usage, and progress events."""

    def __init__(self, task_id, run_id, meta):
        self.task_id = task_id
        self.run_id = run_id

View on GitHub (pinned to 985456f4ad)

Solutions

  1. Raise or remove the budget: run(..., budget_total=None) for unlimited, or size it to expected agents x mean cost
  2. Check budget.remaining() before expensive agent() calls and exit gracefully
  3. Trim prompt/schema sizes if a single call approaches the total

Example fix

# before
run(workflow, meta=meta, budget_total=5000)  # too small for the fan-out

# after
run(workflow, meta=meta, budget_total=200_000)
Defensive patterns

Strategy: validation

Validate before calling

# before each expensive call inside the workflow:
if state.budget.remaining() < ESTIMATED_TOKENS_PER_CALL:
    state.task.update("halted: token budget nearly exhausted")
    return  # exit gracefully instead of letting Budget.add raise

Try / catch

try:
    result = state.agent(prompt, schema=schema)
except WorkflowInputError as exc:
    if "token budget exceeded" not in str(exc):
        raise
    state.task.update("stopped: token budget exceeded")
    return  # or re-run with a raised budget_total after operator approval

Prevention

When it happens

Trigger: Launching with run(..., budget_total=N) and the workflow's cumulative agent usage reaching N — the agent() call whose cost tips over the limit raises. Large schemas/prompts with per-call costs comparable to the whole budget. Fan-out workflows whose parallel agent() calls each add to the same Budget.

Common situations: Iterating on a workflow with a small test budget left in place for production. Model/pricing changes making per-call token counts larger than when the budget was sized. Loops with weak termination conditions consuming budget steadily.

Related errors


AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14). Data as JSON: /api/errors/ca17a6279d776e9d. Report an issue: GitHub.