huggingface/smolagents · error · ValueError
Multiple @tool decorators found on function '{func_node.name
Error message
Multiple @tool decorators found on function '{func_node.name}'. Only one @tool decorator is allowed. What it means
While parsing the decorated function's AST, smolagents found more than one plain `@tool` decorator (ast.Name nodes named 'tool') applied to the same function. Duplicate decoration would wrap the tool twice and corrupt schema generation, so it raises ValueError.
Source
Thrown at src/smolagents/tools.py:1130
# Create and attach the source code of the dynamically created tool class and forward method
# - Get the source code of tool_function
tool_source = textwrap.dedent(inspect.getsource(tool_function))
# - Remove the tool decorator and function definition line
lines = tool_source.splitlines()
tree = ast.parse(tool_source)
# - Find function definition
func_node = next((node for node in ast.walk(tree) if isinstance(node, ast.FunctionDef)), None)
if not func_node:
raise ValueError(
f"No function definition found in the provided source of {tool_function.__name__}. "
"Ensure the input is a standard function."
)
# - Extract decorator lines
decorator_lines = ""
if func_node.decorator_list:
tool_decorators = [d for d in func_node.decorator_list if isinstance(d, ast.Name) and d.id == "tool"]
if len(tool_decorators) > 1:
raise ValueError(
f"Multiple @tool decorators found on function '{func_node.name}'. Only one @tool decorator is allowed."
)
if len(tool_decorators) < len(func_node.decorator_list):
warnings.warn(
f"Function '{func_node.name}' has decorators other than @tool. "
"This may cause issues with serialization in the remote executor. See issue #1626."
)
decorator_start = tool_decorators[0].end_lineno if tool_decorators else 0
decorator_end = func_node.decorator_list[-1].end_lineno
decorator_lines = "\n".join(lines[decorator_start:decorator_end])
# - Extract tool source body
body_start = func_node.body[0].lineno - 1 # AST lineno starts at 1
tool_source_body = "\n".join(lines[body_start:])
# - Create the forward method source, including def line and indentation
forward_method_source = f"def forward{new_sig}:\n{tool_source_body}"
# - Create the class source
indent = " " * 4 # for class method
class_source = (View on GitHub (pinned to 30bb116109)
Solutions
- Remove the duplicate @tool decorator, leaving exactly one
- If decorating programmatically, ensure the input is a raw function, not an already-wrapped Tool
- Check imports to confirm you're not decorating an already-processed function from another module
Example fix
# before
@tool
@tool
def add(a: int, b: int) -> int:
return a + b
# after
@tool
def add(a: int, b: int) -> int:
return a + b Defensive patterns
Strategy: validation
Validate before calling
import ast, inspect
src = inspect.getsource(my_func)
fn = next(n for n in ast.walk(ast.parse(src)) if isinstance(n, ast.FunctionDef))
names = [d.id for d in fn.decorator_list if isinstance(d, ast.Name)]
assert names.count("tool") <= 1, "remove duplicate @tool" Try / catch
try:
my_tool = tool(my_func)
except ValueError as e:
if "Multiple @tool decorators" in str(e):
raise # fix the source; do not retry programmatically
raise Prevention
- Apply @tool exactly once per function
- Never decorate a function that is already a Tool instance
- Review merged/duplicated decorator lines during refactors
When it happens
Trigger: Stacking @tool twice, e.g. `@tool\n@tool\ndef f(...)`, or applying @tool to a function that was already converted to a Tool by another @tool call. Calling `tool(tool(func))` programmatically can produce the same result.
Common situations: Copy-paste accidents during refactoring; migration code that applies @tool on top of already-decorated imports; lint-disabled duplicates after merges.
Related errors
- No function definition found in the provided source of {tool
- Unsupported comparison operator: {op}
- {expression.__class__.__name__} is not supported.
- Source code must define a class
- Tool return type not found: make sure your function has a re
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/26c065d6fa6ca3fb.
Report an issue: GitHub.