{"record":{"id":"82b69a759284929e","repo":"huggingface/smolagents","slug":"you-must-set-an-attribute-attr","errorCode":null,"errorMessage":"You must set an attribute {attr}.","messagePattern":"You must set an attribute (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/smolagents/tools.py","lineNumber":155,"sourceCode":"    def __init__(self, *args, **kwargs):\n        self.is_initialized = False\n\n    def __init_subclass__(cls, **kwargs):\n        super().__init_subclass__(**kwargs)\n        validate_after_init(cls)\n\n    def validate_arguments(self):\n        required_attributes = {\n            \"description\": str,\n            \"name\": str,\n            \"inputs\": dict,\n            \"output_type\": str,\n        }\n        # Validate class attributes\n        for attr, expected_type in required_attributes.items():\n            attr_value = getattr(self, attr, None)\n            if attr_value is None:\n                raise TypeError(f\"You must set an attribute {attr}.\")\n            if not isinstance(attr_value, expected_type):\n                raise TypeError(\n                    f\"Attribute {attr} should have type {expected_type.__name__}, got {type(attr_value)} instead.\"\n                )\n\n        # Validate optional output_schema attribute\n        output_schema = getattr(self, \"output_schema\", None)\n        if output_schema is not None and not isinstance(output_schema, dict):\n            raise TypeError(f\"Attribute output_schema should have type dict, got {type(output_schema)} instead.\")\n\n        # - Validate name\n        if not is_valid_name(self.name):\n            raise Exception(\n                f\"Invalid Tool name '{self.name}': must be a valid Python identifier and not a reserved keyword\"\n            )\n        # Validate inputs\n        for input_name, input_content in self.inputs.items():\n            assert isinstance(input_content, dict), f\"Input '{input_name}' should be a dictionary.\"","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/tools.py#L137-L173","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add the missing attribute named in the message with the right type: name: str, description: str, inputs: dict, output_type: str","Copy the canonical tool skeleton from smolagents docs and fill in all four fields","If subclassing an existing tool, ensure the parent actually defines all four attributes"],"exampleFix":"# before\nclass MyTool(Tool):\n    name = \"my_tool\"\n    description = \"does a thing\"\n    inputs = {\"query\": {\"type\": \"string\", \"description\": \"q\"}}\n    # output_type missing -> TypeError\n\n# after\nclass MyTool(Tool):\n    name = \"my_tool\"\n    description = \"does a thing\"\n    inputs = {\"query\": {\"type\": \"string\", \"description\": \"q\"}}\n    output_type = \"text\"","handlingStrategy":"validation","validationCode":"REQUIRED = {\"name\": str, \"description\": str, \"inputs\": dict, \"output_type\": str}\ndef tool_complete(cls) -> bool:\n    return all(getattr(cls, a, None) is not None for a in REQUIRED)","typeGuard":"def is_valid_tool(cls) -> bool:\n    return isinstance(cls, type) and issubclass(cls, __import__(\"smolagents\").Tool) and tool_complete(cls)","tryCatchPattern":"try:\n    MyTool()\nexcept TypeError as e:\n    if \"must set an attribute\" in str(e):\n        # add the named attribute to the class\n        raise","preventionTips":["Start every tool from the canonical 4-attribute skeleton","Assert all required attributes in tool unit tests","Don't set attributes to None in subclasses"],"tags":["smolagents","tool","validation","missing-attribute"],"backgroundTag":"missing-required-attribute","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}