bazelbuild/bazel · error · EvalException
Starlark computation cancelled: too many steps
Error message
Starlark computation cancelled: too many steps
What it means
Starlark executes scripts within a step budget: every executed statement increments a counter, and when it reaches the thread's stepLimit the interpreter aborts with EvalException 'Starlark computation cancelled: too many steps'. This is a safety valve against infinite loops, since Starlark has no other resource control for unbounded loops. This instance is the check in statement execution (exec).
Source
Thrown at src/main/java/net/starlark/java/eval/Eval.java:326
// Assign a value to the type alias identifier only if type tagging is enabled.
if (typeTable != null) {
TypeConstructor typeConstructor =
checkNotNull(typeTable.getTypeConstructor(node.getIdentifier().getBinding()));
assignIdentifier(fr, node.getIdentifier(), TypeConstructorValue.of(typeConstructor));
}
return TokenKind.PASS;
}
private static TokenKind exec(StarlarkThread.Frame fr, Statement st)
throws EvalException, InterruptedException {
if (fr.dbg != null) {
Location loc = st.getStartLocation(); // not very precise
fr.setLocation(loc);
fr.dbg.before(fr.thread, loc); // location is now redundant since it's in the thread
}
if (++fr.thread.steps >= fr.thread.stepLimit) {
throw new EvalException("Starlark computation cancelled: too many steps");
}
switch (st.kind()) {
case ASSIGNMENT:
execAssignment(fr, (AssignmentStatement) st);
return TokenKind.PASS;
case EXPRESSION:
eval(fr, ((ExpressionStatement) st).getExpression());
return TokenKind.PASS;
case FLOW:
return ((FlowStatement) st).getFlowKind();
case FOR:
return execFor(fr, (ForStatement) st);
case DEF:
DefStatement def = (DefStatement) st;
StarlarkFunction fn = newFunction(fr, def.getResolvedFunction());
assignIdentifier(fr, def.getIdentifier(), fn);
return TokenKind.PASS;View on GitHub (pinned to e6e199d060)
Solutions
- Fix the script: ensure loop termination conditions actually progress (bump the counter/index, correct the break condition).
- If the computation is legitimately large, raise the budget: StarlarkThread.setStepLimit(n) (or the host application's configured limit) before evaluation.
- Reproduce locally with a debug print/log every N iterations to find the non-terminating loop.
- Move the heavy computation into a native (Java) Starlark builtin instead of a Starlark loop.
Example fix
# before
def collect(items):
out = []
i = 0
while i < len(items): # i never incremented -> infinite
out.append(items[i])
return out
# after
def collect(items):
return list(items) Defensive patterns
Strategy: try-catch
Try / catch
try {
Starlark.execFile(thread, parsedFile);
} catch (EvalException e) {
if (e.getMessage().contains("too many steps")) {
// script exceeded budget: fix the loop or raise setStepLimit
} else {
throw e;
}
} Prevention
- Set an explicit, generous stepLimit with StarlarkThread.setStepLimit() sized to the workload.
- Review every while-loop and large for-loop in scripts for guaranteed progress.
- Log loop iteration counts during development to catch growth before the limit does.
When it happens
Trigger: A script with an unbounded or huge loop (while True:, for over an enormous range/list), runaway recursion expressed iteratively, or a legitimately long computation whose step count exceeds the configured limit; StarlarkThread.stepLimit set low or left at default.
Common situations: BUILD/.bzl or macro logic with a loop over all targets that grows with the repository; regression where a loop condition never becomes false; evaluators (REPL, tests) running with a small stepLimit for fast failure.
Related errors
- isinstance() is not yet supported
- This converter doesn't support Starlark reversal.
- Invalid options syntax: %s Note: Negative target patterns ca
- Expected one of %s and %s to be a subclass of the other
- Class %s has an incompatible overload of annotated method %s
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/1dda34d04d3761ae.
Report an issue: GitHub.