huggingface/smolagents · warning · UserWarning

Function '{func_node.name}' has decorators other than @tool.

Error message

Function '{func_node.name}' has decorators other than @tool. This may cause issues with serialization in the remote executor. See issue #1626.

What it means

The `@tool` decorator serializes your function's source code (it strips/reconstructs decorators) so it can be shipped to a remote code executor. If the function has decorators beyond a single `@tool`, they cannot be serialized faithfully, and smolagents warns that this may break remote execution (GitHub issue #1626).

Source

Thrown at src/smolagents/tools.py:1134

    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 = (
        textwrap.dedent(f"""
        class SimpleTool(Tool):
            name: str = "{tool_json_schema["name"]}"
            description: str = {json.dumps(textwrap.dedent(tool_json_schema["description"]).strip())}

View on GitHub (pinned to 30bb116109)

Solutions

  1. Remove the extra decorators from the @tool function; move caching/wrapping inside the function body
  2. Apply the other decorator OUTSIDE @tool only if remote execution isn't needed, otherwise restructure: write an undecorated function, decorate it with @tool, and cache at call sites
  3. If you don't use remote/egress code execution, the warning can be ignored, but reordering so @tool is outermost avoids the serialization issue

Example fix

# before
@tool
@lru_cache(maxsize=None)
def fetch_price(ticker: str) -> str:
    ...

# after
def _fetch_price(ticker: str) -> str: ...

@tool
def fetch_price(ticker: str) -> str:
    return _fetch_price(ticker)
Defensive patterns

Strategy: validation

Validate before calling

import ast, inspect

def has_only_tool_decorator(func) -> bool:
    src = inspect.getsource(func.__wrapped__ if hasattr(func, '__wrapped__') else func)
    tree = ast.parse(textwrap.dedent(src))
    fn = tree.body[0]
    return all(isinstance(d, ast.Name) and d.id == 'tool' for d in fn.decorator_list)

Prevention

When it happens

Trigger: Applying `@tool` to a function that also has other decorators, e.g. `@functools.lru_cache`, `@staticmethod`, `@some_decorator` stacked with `@tool`. The AST check `len(tool_decorators) < len(func_node.decorator_list)` fires the warning during `tool()` decoration.

Common situations: Decorating cached or wrapped helper functions with `@tool`; using `@tool` on methods inside classes with additional decorators; decorator order like `@lru_cache` above `@tool` causing wrong serialization for egress-executed tools.

Related errors


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