huggingface/smolagents · error · InterpreterError
Unsupported statement in class body
Error message
Unsupported statement in class body: {stmt.__class__.__name__} What it means
evaluate_class_def only supports a fixed set of statements inside a class body (assignments, AnnAssign, FunctionDef, AsyncFunctionDef, Pass, Expr docstrings); anything else (if, for, while, try, with, Return, etc.) raises InterpreterError naming the statement class. Python itself forbids many of these in class bodies, but the executor is stricter.
Solutions
- Move conditional/loop logic out of the class body into __init__ or a classmethod
- Replace class-body branching with precomputed values or default arguments
- Simplify to plain attribute and method definitions inside the class
Example fix
# before code = "class Config:\n if debug:\n level = 'DEBUG'" # after code = "class Config:\n level = 'DEBUG' if debug else 'INFO'"
Defensive patterns
Strategy: validation
Validate before calling
import ast
ALLOWED = (ast.FunctionDef, ast.AsyncFunctionDef, ast.Assign, ast.AnnAssign, ast.Pass)
for node in ast.walk(ast.parse(code)):
if isinstance(node, ast.ClassDef):
for stmt in node.body:
if not isinstance(stmt, ALLOWED) and not (isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Constant)):
raise ValueError(f'statement {type(stmt).__name__} not allowed in class body') Try / catch
from smolagents.local_python_executor import InterpreterError
try:
evaluate_python(code)
except InterpreterError as e:
if 'Unsupported statement in class body' in str(e):
code = move_logic_to_init(code) Prevention
- Put branching/loops inside methods (__init__), never in the class body
- Use conditional expressions (x = a if c else b) for conditional attributes
- Lint generated code for non-trivial class bodies before execution
When it happens
Trigger: Class body contains an unsupported statement, e.g. `class A:\n if x: y = 1`, a for loop, a with block, or a raise, inside the executed snippet.
Common situations: LLM generates conditional initialization or loops inside a class; metaprogramming-style code pasted into the agent; code that is valid at module level pasted verbatim into a class body.
Related errors
- Cannot unpack non-tuple value
- Cannot unpack tuple of wrong size
- Forbidden access to function
- Forbidden access to module
- Forbidden access to module
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/f177503093f73ec2.
Report an issue: GitHub.
Appendix: source
Thrown at src/smolagents/local_python_executor.py:614
value = evaluate_ast(stmt.value, state, static_tools, custom_tools, authorized_imports)
for target in stmt.targets:
if isinstance(target, ast.Name):
class_dict[target.id] = value
elif isinstance(target, ast.Attribute):
obj = evaluate_ast(target.value, class_dict, static_tools, custom_tools, authorized_imports)
setattr(obj, target.attr, value)
elif isinstance(stmt, ast.Pass):
pass
elif (
isinstance(stmt, ast.Expr)
and stmt == class_def.body[0]
and isinstance(stmt.value, ast.Constant)
and isinstance(stmt.value.value, str)
):
# Check if it is a docstring: first statement in class body which is a string literal expression
class_dict["__doc__"] = stmt.value.value
else:
raise InterpreterError(f"Unsupported statement in class body: {stmt.__class__.__name__}")
new_class = metaclass(class_name, tuple(bases), class_dict)
state[class_name] = new_class
return new_class
def evaluate_annassign(
annassign: ast.AnnAssign,
state: dict[str, Any],
static_tools: dict[str, Callable],
custom_tools: dict[str, Callable],
authorized_imports: list[str],
) -> Any:
# If there's a value to assign, evaluate it
if annassign.value:
value = evaluate_ast(annassign.value, state, static_tools, custom_tools, authorized_imports)
# Set the value for the target
set_value(annassign.target, value, state, static_tools, custom_tools, authorized_imports)View on GitHub (pinned to 30bb116109)