huggingface/smolagents · critical · InterpreterError

Forbidden access to function: {function_name}

Error message

Forbidden access to function: {function_name}

What it means

check_safer_result blocks return values that are functions listed in smolagents' DANGEROUS_FUNCTIONS (e.g. os.system, eval, exec, builtins.compile) unless they are exposed as static tools. If executed code returns such a function and its __name__ matches a dangerous qualified name's function part and its __module__ matches, an InterpreterError is raised.

Source

Thrown at src/smolagents/local_python_executor.py:182

    Raises:
        InterpreterError: If the result is not safe
    """
    if isinstance(result, ModuleType):
        if not check_import_authorized(result.__name__, authorized_imports):
            raise InterpreterError(f"Forbidden access to module: {result.__name__}")
    elif isinstance(result, dict) and result.get("__spec__"):
        if not check_import_authorized(result["__name__"], authorized_imports):
            raise InterpreterError(f"Forbidden access to module: {result['__name__']}")
    elif isinstance(result, (FunctionType, BuiltinFunctionType)):
        for qualified_function_name in DANGEROUS_FUNCTIONS:
            module_name, function_name = qualified_function_name.rsplit(".", 1)
            if (
                (static_tools is None or function_name not in static_tools)
                and result.__name__ == function_name
                and result.__module__ == module_name
            ):
                raise InterpreterError(f"Forbidden access to function: {function_name}")


def safer_eval(func: Callable):
    """
    Decorator to enhance the security of an evaluation function by checking its return value.

    Args:
        func (Callable): Evaluation function to be made safer.

    Returns:
        Callable: Safer evaluation function with return value check.
    """

    @wraps(func)
    def _check_return(
        expression,
        state,
        static_tools,

View on GitHub (pinned to 30bb116109)

Solutions

  1. Rewrite the code to perform the operation inside the sandbox and return its result instead of the dangerous function
  2. If you truly need the capability, pass it in as a static tool (add to tools=[...]) so the name check exempts it
  3. Prompt/instruct the agent never to return functions, only serializable results

Example fix

# before
code = "import os
os.system"

# after
code = "import os
final_answer(os.system('ls').returncode)"
Defensive patterns

Strategy: validation

Validate before calling

import inspect
DANGEROUS = {'os.system', 'builtins.eval', 'builtins.exec', 'builtins.compile', 'builtins.open'}
def is_dangerous_callable(v, static_tools) -> bool:
    return (callable(v) and not (static_tools and v.__name__ in static_tools)
            and f"{getattr(v, '__module__', '')}.{getattr(v, '__name__', '')}" in DANGEROUS)

Type guard

def is_dangerous_callable(v, static_tools) -> bool:
    return callable(v) and getattr(v, '__name__', '') in {'system', 'eval', 'exec', 'compile'}

Try / catch

from smolagents.local_python_executor import InterpreterError
try:
    evaluate_python(code)
except InterpreterError as e:
    if 'Forbidden access to function' in str(e):
        raise SecurityViolation(str(e)) from e

Prevention

When it happens

Trigger: Executed code's final expression or a decorated function returns a DANGEROUS_FUNCTIONS entry, e.g. `import os` then `os.system`, or `__import__('builtins').eval`, and the function name is not present in static_tools.

Common situations: LLM tries to get the sandbox to hand back os.system/eval so the caller can invoke it outside the sandbox; returning open or input builtins; the model 'helpfully' returns a process-spawning callable as the answer.

Understand the failure class

Related errors


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