huggingface/smolagents · error · TypeError

You must set an attribute {attr}.

Error message

You must set an attribute {attr}.

What it means

Every smolagents Tool must declare class attributes name, description, inputs, and output_type. Tool.__init_subclass__ wraps __init__ with new_init, which calls validate_arguments; if any of these required attributes is None/missing, it raises TypeError('You must set an attribute {attr}.'). The message names the first missing attribute in validation order (name, description, inputs, output_type).

Source

Thrown at src/smolagents/tools.py:155

    def __init__(self, *args, **kwargs):
        self.is_initialized = False

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        validate_after_init(cls)

    def validate_arguments(self):
        required_attributes = {
            "description": str,
            "name": str,
            "inputs": dict,
            "output_type": str,
        }
        # Validate class attributes
        for attr, expected_type in required_attributes.items():
            attr_value = getattr(self, attr, None)
            if attr_value is None:
                raise TypeError(f"You must set an attribute {attr}.")
            if not isinstance(attr_value, expected_type):
                raise TypeError(
                    f"Attribute {attr} should have type {expected_type.__name__}, got {type(attr_value)} instead."
                )

        # Validate optional output_schema attribute
        output_schema = getattr(self, "output_schema", None)
        if output_schema is not None and not isinstance(output_schema, dict):
            raise TypeError(f"Attribute output_schema should have type dict, got {type(output_schema)} instead.")

        # - Validate name
        if not is_valid_name(self.name):
            raise Exception(
                f"Invalid Tool name '{self.name}': must be a valid Python identifier and not a reserved keyword"
            )
        # Validate inputs
        for input_name, input_content in self.inputs.items():
            assert isinstance(input_content, dict), f"Input '{input_name}' should be a dictionary."

View on GitHub (pinned to 30bb116109)

Solutions

  1. Add the missing attribute named in the message with the right type: name: str, description: str, inputs: dict, output_type: str
  2. Copy the canonical tool skeleton from smolagents docs and fill in all four fields
  3. If subclassing an existing tool, ensure the parent actually defines all four attributes

Example fix

# before
class MyTool(Tool):
    name = "my_tool"
    description = "does a thing"
    inputs = {"query": {"type": "string", "description": "q"}}
    # output_type missing -> TypeError

# after
class MyTool(Tool):
    name = "my_tool"
    description = "does a thing"
    inputs = {"query": {"type": "string", "description": "q"}}
    output_type = "text"
Defensive patterns

Strategy: validation

Validate before calling

REQUIRED = {"name": str, "description": str, "inputs": dict, "output_type": str}
def tool_complete(cls) -> bool:
    return all(getattr(cls, a, None) is not None for a in REQUIRED)

Type guard

def is_valid_tool(cls) -> bool:
    return isinstance(cls, type) and issubclass(cls, __import__("smolagents").Tool) and tool_complete(cls)

Try / catch

try:
    MyTool()
except TypeError as e:
    if "must set an attribute" in str(e):
        # add the named attribute to the class
        raise

Prevention

When it happens

Trigger: Subclassing Tool (or instantiating one) without defining one of: name (str), description (str), inputs (dict), output_type (str); the error fires at instantiation via new_init → validate_arguments.

Common situations: Writing a custom tool and forgetting output_type or description; copy-pasting a tool template and deleting a field; overriding attributes to None in a subclass; upgrading smolagents where new attributes became required.

Related errors


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