rohitg00/ai-engineering-from-scratch · error · RangeError
Budget.step requires non-negative tokens and dollars
Error message
Budget.step requires non-negative tokens and dollars
What it means
Budget.step throws a RangeError when passed a negative token count or dollar amount; the agent's per-run budget ledger refuses to record negative usage so it can never be inflated into a refund. Called from the main agent loop for every model turn.
Source
Thrown at phases/19-capstone-projects/01-terminal-native-coding-agent/code/ts/src/plan.ts:41
const lines = [`GOAL: ${this.goal}`];
for (const it of this.items) {
lines.push(` [${mark[it.status]}] ${it.id}. ${it.description}`);
}
return lines.join("\n");
}
}
export class Budget {
maxTurns = 50;
maxTokens = 200_000;
maxDollars = 5.0;
turnsUsed = 0;
tokensUsed = 0;
dollarsUsed = 0;
step(tokens: number, dollars: number): void {
if (tokens < 0 || dollars < 0) {
throw new RangeError("Budget.step requires non-negative tokens and dollars");
}
this.turnsUsed += 1;
this.tokensUsed += tokens;
this.dollarsUsed += dollars;
}
exceeded(): string | null {
if (this.turnsUsed >= this.maxTurns) return "turn_limit";
if (this.tokensUsed >= this.maxTokens) return "token_limit";
if (this.dollarsUsed >= this.maxDollars) return "dollar_limit";
return null;
}
snapshot(): { turnsUsed: number; tokensUsed: number; dollarsUsed: number } {
return {
turnsUsed: this.turnsUsed,
tokensUsed: this.tokensUsed,
dollarsUsed: this.dollarsUsed,View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Clamp usage to 0 before calling step: step(Math.max(0,t), Math.max(0,d))
- Fix the provider adapter that produced negative usage numbers
- Model refunds as a separate ledger method, not negative step()
Example fix
// before budget.step(usage.tokens - previousTokens, usage.dollars); // after budget.step(Math.max(0, usage.tokens - previousTokens), Math.max(0, usage.dollars));
Defensive patterns
Strategy: validation
Validate before calling
if (tokens < 0 || dollars < 0) return; // or clamp budget.step(Math.max(0, tokens), Math.max(0, dollars));
Try / catch
try { budget.step(t, d); } catch (e) { if (e instanceof RangeError) logBadUsage(t, d); else throw e; } Prevention
- Validate provider usage fields before recording them
- Keep refunds in a separate ledger field, never negative step()
When it happens
Trigger: Calling step(-100, 0.01), step(500, -0.02), or passing NaN comparisons gone wrong (NaN fails the <0 check but still poisons totals only if negative). Specifically any invocation where tokens<0 or dollars<0.
Common situations: Mocked model clients returning negative usage fields, refund/credit accounting wired directly into step, or computing deltas where a later reading is subtracted from an earlier one.
Related errors
- -32600
- -32602
- -32603
- path escapes sandbox: ${(err as Error).message}
- tool_use requires name and object input
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/897cec579a1e4e19.
Report an issue: GitHub.