huggingface/smolagents · error · InterpreterError

Cannot assign to name '{target.id}': doing this would erase

Error message

Cannot assign to name '{target.id}': doing this would erase the existing tool!

What it means

set_value refuses ast.Name assignments whose id collides with a key in static_tools: overwriting would shadow/remove a registered tool for the rest of the execution. The executor raises InterpreterError telling you the assignment would erase the tool.

Source

Thrown at src/smolagents/local_python_executor.py:804

            else:
                expanded_values.append(result)

        for tgt, val in zip(assign.targets, expanded_values):
            set_value(tgt, val, state, static_tools, custom_tools, authorized_imports)
    return result


def set_value(
    target: ast.AST,
    value: Any,
    state: dict[str, Any],
    static_tools: dict[str, Callable],
    custom_tools: dict[str, Callable],
    authorized_imports: list[str],
) -> None:
    if isinstance(target, ast.Name):
        if target.id in static_tools:
            raise InterpreterError(f"Cannot assign to name '{target.id}': doing this would erase the existing tool!")
        state[target.id] = value
    elif isinstance(target, ast.Tuple):
        if not isinstance(value, tuple):
            if hasattr(value, "__iter__") and not isinstance(value, (str, bytes)):
                value = tuple(value)
            else:
                raise InterpreterError("Cannot unpack non-tuple value")
        if len(target.elts) != len(value):
            raise InterpreterError("Cannot unpack tuple of wrong size")
        for i, elem in enumerate(target.elts):
            set_value(elem, value[i], state, static_tools, custom_tools, authorized_imports)
    elif isinstance(target, ast.Subscript):
        obj = evaluate_ast(target.value, state, static_tools, custom_tools, authorized_imports)
        key = evaluate_ast(target.slice, state, static_tools, custom_tools, authorized_imports)
        obj[key] = value
    elif isinstance(target, ast.Attribute):
        obj = evaluate_ast(target.value, state, static_tools, custom_tools, authorized_imports)
        setattr(obj, target.attr, value)

View on GitHub (pinned to 30bb116109)

Solutions

  1. Rename the variable in the generated code to something non-colliding (e.g. search_result instead of search)
  2. Rename the custom tool to a less generic name when registering it
  3. Prompt the agent with the list of reserved tool names and instruct it to avoid them as identifiers

Example fix

# before
code = "search = 'query text'\nfinal_answer(search)"

# after
code = "search_query = 'query text'\nfinal_answer(search_query)"
Defensive patterns

Strategy: validation

Validate before calling

import ast
reserved = set(static_tools)  # e.g. {'search', 'final_answer'}
for node in ast.walk(ast.parse(code)):
    names = set()
    if isinstance(node, (ast.Assign, ast.AnnAssign, ast.AugAssign)):
        targets = node.targets if isinstance(node, ast.Assign) else [node.target]
        names |= {t.id for t in targets if isinstance(t, ast.Name)}
    if isinstance(node, (ast.For, ast.comprehension)):
        names |= {n.id for n in ast.walk(node.target) if isinstance(n, ast.Name)}
    clash = names & reserved
    if clash:
        raise ValueError(f'variable names shadow tools: {clash}')

Try / catch

from smolagents.local_python_executor import InterpreterError
try:
    evaluate_python(code, static_tools=static_tools)
except InterpreterError as e:
    if 'would erase the existing tool' in str(e):
        code = rename_shadowed_vars(code, avoid=set(static_tools))
        evaluate_python(code, static_tools=static_tools)

Prevention

When it happens

Trigger: Executed code assigns to a name that is a static tool: e.g. with a registered tool named 'search', code containing `search = 'foo'`, `search, x = 1, 2`, or a for-loop target/comprehension variable named `search`. The check applies to Assign, AnnAssign, AugAssign targets, for-loops and comprehensions.

Common situations: LLM picks a generic variable name that matches a tool name ('search', 'final_answer', 'visit_webpage'); tuple unpacking or iteration reuses a tool name; user names their custom tool something common like 'read' or 'get'.

Related errors


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