huggingface/smolagents · error · InterpreterError

Maximum number of {MAX_WHILE_ITERATIONS} iterations in While

Error message

Maximum number of {MAX_WHILE_ITERATIONS} iterations in While loop exceeded

What it means

The executor caps while loops at MAX_WHILE_ITERATIONS (100_000) iterations to prevent runaway generated code; exceeding it raises InterpreterError even though the condition may still be true. This is a CPU-bound guard independent of the wall-clock timeout.

Source

Thrown at src/smolagents/local_python_executor.py:458

def evaluate_while(
    while_loop: ast.While,
    state: dict[str, Any],
    static_tools: dict[str, Callable],
    custom_tools: dict[str, Callable],
    authorized_imports: list[str],
) -> None:
    iterations = 0
    while evaluate_ast(while_loop.test, state, static_tools, custom_tools, authorized_imports):
        for node in while_loop.body:
            try:
                evaluate_ast(node, state, static_tools, custom_tools, authorized_imports)
            except BreakException:
                return None
            except ContinueException:
                break
        iterations += 1
        if iterations > MAX_WHILE_ITERATIONS:
            raise InterpreterError(f"Maximum number of {MAX_WHILE_ITERATIONS} iterations in While loop exceeded")
    return None


def create_function(
    func_def: ast.FunctionDef,
    state: dict[str, Any],
    static_tools: dict[str, Callable],
    custom_tools: dict[str, Callable],
    authorized_imports: list[str],
) -> Callable:
    source_code = ast.unparse(func_def)

    def new_func(*args: Any, **kwargs: Any) -> Any:
        func_state = state.copy()
        arg_names = [arg.arg for arg in func_def.args.args]
        default_values = [
            evaluate_ast(d, state, static_tools, custom_tools, authorized_imports) for d in func_def.args.defaults
        ]

View on GitHub (pinned to 30bb116109)

Solutions

  1. Add an explicit iteration cap and break in the loop: `for _ in range(10_000): ... ` or `i += 1; if i > N: break`
  2. Fix the loop condition/counter so it actually converges (verify the mutated variable is the one tested)
  3. Convert the while to a bounded for-range loop, which is easier for the model to get right

Example fix

# before
code = "i = 0\nwhile True:\n    i += 1\nfinal_answer(i)"

# after
code = "i = 0\nwhile i < 100:\n    i += 1\nfinal_answer(i)"
Defensive patterns

Strategy: validation

Validate before calling

import ast
MAX = 100_000
for node in ast.walk(ast.parse(code)):
    if isinstance(node, ast.While):
        has_break = any(isinstance(x, ast.Break) for x in ast.walk(node))
        has_cap = 'max_iter' in code or 'range(' in ast.dump(node)
        if not (has_break or has_cap):
            raise ValueError('unbounded while loop detected; add a counter/break')

Try / catch

from smolagents.local_python_executor import InterpreterError
try:
    evaluate_python(code)
except InterpreterError as e:
    if 'While loop exceeded' in str(e):
        code = code.replace('while True', 'for _ in range(10000)')
        evaluate_python(code)

Prevention

When it happens

Trigger: A while loop in executed code runs more than MAX_WHILE_ITERATIONS times: `while True:` with no break, `while x != target:` that never converges, or a loop whose counter update is wrong (e.g. decrementing a variable it never reads).

Common situations: LLM writes `while True` intending a few iterations; loop variable shadowed or updated inside an inner function so the condition never changes; searching without a bound; off-by-one making the exit condition unreachable.

Related errors


AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28). Data as JSON: /api/errors/5c15d48a604092cb. Report an issue: GitHub.