{"record":{"id":"9c4dc4390f5d25ef","repo":"huggingface/smolagents","slug":"attribute-output-schema-should-have-type-dict-got","errorCode":null,"errorMessage":"Attribute output_schema should have type dict, got {type(output_schema)} instead.","messagePattern":"Attribute output_schema should have type dict, got (.+?) instead\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/smolagents/tools.py","lineNumber":164,"sourceCode":"            \"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.\"\n            assert \"type\" in input_content and \"description\" in input_content, (\n                f\"Input '{input_name}' should have keys 'type' and 'description', has only {list(input_content.keys())}.\"\n            )\n            # Get input_types as a list, whether from a string or list\n            if isinstance(input_content[\"type\"], str):\n                input_types = [input_content[\"type\"]]\n            elif isinstance(input_content[\"type\"], list):\n                input_types = input_content[\"type\"]\n                # Check if all elements are strings","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/tools.py#L146-L182","documentation":"The optional Tool.output_schema attribute, when set, must be a dict (JSON-schema style). validate_arguments raises TypeError if output_schema is present but is any other type. Leaving it unset (None) is fine; the check only applies when you provide it.","triggerScenarios":"Setting output_schema to a JSON string, a pydantic model, a list, or any non-dict value on a Tool subclass; error fires at instantiation via new_init → validate_arguments.","commonSituations":"Copy-pasting a JSON schema from docs as a string instead of parsing it into a dict; assigning a pydantic BaseModel class or .model_json_schema() result's string form; refactoring a tool from dict-based to string-based config.","solutions":["Convert the value to a dict, e.g. json.loads(schema_string) or use the already-parsed schema object","If using pydantic, pass MyModel.model_json_schema() (which returns a dict), not the model class","Remove output_schema entirely if the tool returns plain text"],"exampleFix":"# before\nclass MyTool(Tool):\n    output_schema = '{\"type\": \"object\", ...}'  # str -> TypeError\n\n# after\nclass MyTool(Tool):\n    output_schema = {\"type\": \"object\", \"properties\": {\"result\": {\"type\": \"string\"}}}","handlingStrategy":"type-guard","validationCode":"schema = getattr(MyTool, \"output_schema\", None)\nassert schema is None or isinstance(schema, dict), \"output_schema must be a dict\"","typeGuard":"def output_schema_ok(cls) -> bool:\n    s = getattr(cls, \"output_schema\", None)\n    return s is None or isinstance(s, dict)","tryCatchPattern":"try:\n    MyTool()\nexcept TypeError as e:\n    if \"output_schema\" in str(e):\n        MyTool.output_schema = dict(MyTool.output_schema)  # or parse JSON string\n        MyTool()","preventionTips":["Use pydantic's model_json_schema() (returns dict) directly","json.loads() any schema string before assigning","Omit output_schema for plain-text tools"],"tags":["smolagents","tool","type-error","json-schema"],"backgroundTag":"attribute-type-mismatch","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}