huggingface/smolagents · error · InterpreterError
Forbidden function evaluation: '{call.func.id}' is not among
Error message
Forbidden function evaluation: '{call.func.id}' is not among the explicitly allowed tools or defined/imported in the preceding code What it means
For a bare-name call f(...), evaluate_call looks the name up in state (code-defined variables/imports), static_tools, custom_tools, and the built-in ERRORS dict; if it is found nowhere, the interpreter treats it as an unauthorized call and raises InterpreterError. This is the sandbox's NameError equivalent with a security rationale: only explicitly provided tools and code-defined/imported names may be called.
Source
Thrown at src/smolagents/local_python_executor.py:858
func = evaluate_ast(call.func, state, static_tools, custom_tools, authorized_imports)
elif isinstance(call.func, ast.Attribute):
obj = evaluate_ast(call.func.value, state, static_tools, custom_tools, authorized_imports)
func_name = call.func.attr
if not hasattr(obj, func_name):
raise InterpreterError(f"Object {obj} has no attribute {func_name}")
func = getattr(obj, func_name)
elif isinstance(call.func, ast.Name):
func_name = call.func.id
if func_name in state:
func = state[func_name]
elif func_name in static_tools:
func = static_tools[func_name]
elif func_name in custom_tools:
func = custom_tools[func_name]
elif func_name in ERRORS:
func = ERRORS[func_name]
else:
raise InterpreterError(
f"Forbidden function evaluation: '{call.func.id}' is not among the explicitly allowed tools or defined/imported in the preceding code"
)
elif isinstance(call.func, ast.Subscript):
func = evaluate_ast(call.func, state, static_tools, custom_tools, authorized_imports)
if not callable(func):
raise InterpreterError(f"This is not a correct function: {call.func}).")
func_name = None
args = []
for arg in call.args:
if isinstance(arg, ast.Starred):
args.extend(evaluate_ast(arg.value, state, static_tools, custom_tools, authorized_imports))
else:
args.append(evaluate_ast(arg, state, static_tools, custom_tools, authorized_imports))
kwargs = {}
for keyword in call.keywords:
if keyword.arg is None:View on GitHub (pinned to 30bb116109)
Solutions
- Add the missing import inside the executed code (`import pandas as pd` before `pd.read_csv`)
- Define the helper inside the snippet, or pass it as a static/custom tool when constructing the agent
- Check for typos and ensure the name was assigned earlier in the same snippet (state does not persist across separate evaluate_python calls unless you reuse the interpreter state)
Example fix
# before
code = "df = pd.read_csv('data.csv')"
# after
code = "import pandas as pd\ndf = pd.read_csv('data.csv')" Defensive patterns
Strategy: validation
Validate before calling
import ast
code_tree = ast.parse(code)
defined = {n.id for n in ast.walk(code_tree) if isinstance(n, ast.Name) and isinstance(n.ctx, ast.Store)}
defined |= {n.names[0].asname or n.names[0].name.split('.')[0] for n in ast.walk(code_tree) if isinstance(n, ast.Import)}
defined |= {(n.module or '').split('.')[0] for n in ast.walk(code_tree) if isinstance(n, ast.ImportFrom)}
called = {n.func.id for n in ast.walk(code_tree) if isinstance(n, ast.Call) and isinstance(n.func, ast.Name)}
missing = called - defined - set(static_tools) - set(custom_tools)
if missing:
raise ValueError(f'undefined names called: {missing}') Try / catch
from smolagents.local_python_executor import InterpreterError
try:
evaluate_python(code, static_tools=static_tools)
except InterpreterError as e:
if 'Forbidden function evaluation' in str(e):
code = add_missing_imports(code)
evaluate_python(code, static_tools=static_tools) Prevention
- Require generated code to import everything it uses in the same snippet
- Register needed capabilities as static/custom tools up front
- Remember interpreter state resets between runs — redefine helpers each snippet
When it happens
Trigger: Executed code calls a function never defined or imported in the snippet and not among the tools: `print(x)` is fine (builtins) but e.g. `pd.read_csv(...)` without `import pandas as pd`, calling `len` is fine but `search(...)` with no such tool registered, or calling a name defined only in another cell/before a state reset.
Common situations: LLM forgets the import line (very common: using np/pd without importing); calling a tool that was not attached to the agent; relying on variables from a previous evaluation after the interpreter state was reset; typo'd function names.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Forbidden access to module: {result.__name__}
- Forbidden access to module: {result['__name__']}
- Forbidden access to function: {function_name}
- Code execution exceeded the maximum execution time of {timeo
- Object is not iterable
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/38448617387c9430.
Report an issue: GitHub.