huggingface/smolagents · error · ExecutionTimeoutError
Code execution exceeded the maximum execution time of {timeo
Error message
Code execution exceeded the maximum execution time of {timeout_seconds} seconds What it means
smolagents wraps script execution in a single-worker ThreadPoolExecutor with a per-call timeout; if future.result(timeout=...) times out, it converts the timeout into an ExecutionTimeoutError. The background thread keeps running (threads cannot be killed in Python), but the caller gets this error so runaway code cannot hang the agent.
Source
Thrown at src/smolagents/local_python_executor.py:314
ExecutionTimeoutError: If the function execution exceeds the timeout period.
Note:
If a timeout occurs, the thread running the function cannot be forcefully killed
in Python, so it will continue running in the background until completion. However,
the caller will receive a TimeoutError and can continue execution.
"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# Create a new ThreadPoolExecutor for each call to avoid threading issues
with ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(func, *args, **kwargs)
try:
result = future.result(timeout=timeout_seconds)
return result
except FuturesTimeoutError:
raise ExecutionTimeoutError(
f"Code execution exceeded the maximum execution time of {timeout_seconds} seconds"
)
return wrapper
return decorator
def get_iterable(obj):
if isinstance(obj, list):
return obj
elif hasattr(obj, "__iter__"):
return list(obj)
else:
raise InterpreterError("Object is not iterable")
def fix_final_answer_code(code: str) -> str:View on GitHub (pinned to 30bb116109)
Solutions
- Increase or set the timeout: pass run_kwargs={'timeout_seconds': ...} / configure executor timeout appropriately
- Fix the generated code: bound loops, add early exits, reduce data size, or move heavy compute to a separate job
- Pre-test the code snippet standalone to estimate runtime before handing it to the agent
Example fix
# before
result = agent.run(task, extra_variables={...}) # default timeout
# after
result = agent.run(
task,
additional_args={'timeout_seconds': 120},
) Defensive patterns
Strategy: retry
Validate before calling
# dry-run estimate: parse for unbounded loops before executing
import ast
tree = ast.parse(code)
unbounded = [n for n in ast.walk(tree) if isinstance(n, ast.While) and not n.orelse and all(not isinstance(x, ast.Break) for x in ast.walk(n))]
if unbounded:
code = 'max_iter = 10000\n' + code Try / catch
from smolagents.local_python_executor import ExecutionTimeoutError
try:
result = evaluate_python(code, timeout_seconds=60)
except ExecutionTimeoutError:
result = fallback_stub_answer() # note: the thread keeps running in background Prevention
- Set a realistic timeout_seconds based on a standalone dry-run
- Bound every while loop in generated code
- Keep heavy compute out of the sandbox (precompute and pass results in as variables)
When it happens
Trigger: evaluate_python(code, timeout_seconds=N) or a CodeAgent run where the generated code enters an infinite/very long loop (e.g. while True, huge pandas merge, long training loop) exceeding the configured timeout (default max_print_outputs_length-adjacent run settings; commonly N seconds set in run_kwargs).
Common situations: Default timeout too low for heavy compute (model inference, big dataframes); generated code has an unbounded while loop; network call without its own timeout; slow first import of large libraries counting against the budget.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Maximum number of {MAX_WHILE_ITERATIONS} iterations in While
- Reached the max number of operations of {MAX_OPERATIONS}. Ma
- Forbidden access to module: {result.__name__}
- Forbidden access to module: {result['__name__']}
- Forbidden access to function: {function_name}
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/876f4c6dd09a12d9.
Report an issue: GitHub.