{"record":{"id":"6fdba57808aba75b","repo":"huggingface/smolagents","slug":"input-input-name-type-must-be-a-string-or-lis","errorCode":null,"errorMessage":"Input '{input_name}': type must be a string or list of strings, got {type(input_content['type']).__name__}","messagePattern":"Input '(.+?)': type must be a string or list of strings, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/smolagents/tools.py","lineNumber":188,"sourceCode":"            )\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\n                if not all(isinstance(t, str) for t in input_types):\n                    raise TypeError(\n                        f\"Input '{input_name}': when type is a list, all elements must be strings, got {input_content['type']}\"\n                    )\n            else:\n                raise TypeError(\n                    f\"Input '{input_name}': type must be a string or list of strings, got {type(input_content['type']).__name__}\"\n                )\n            # Check all types are authorized\n            invalid_types = [t for t in input_types if t not in AUTHORIZED_TYPES]\n            if invalid_types:\n                raise ValueError(f\"Input '{input_name}': types {invalid_types} must be one of {AUTHORIZED_TYPES}\")\n        # Validate output type\n        assert getattr(self, \"output_type\", None) in AUTHORIZED_TYPES\n\n        # Validate forward function signature, except for Tools that use a \"generic\" signature (PipelineTool, SpaceToolWrapper, LangChainToolWrapper)\n        if not (\n            hasattr(self, \"skip_forward_signature_validation\")\n            and getattr(self, \"skip_forward_signature_validation\") is True\n        ):\n            signature = inspect.signature(self.forward)\n            actual_keys = set(key for key in signature.parameters.keys() if key != \"self\")\n            expected_keys = set(self.inputs.keys())\n            if actual_keys != expected_keys:","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/tools.py#L170-L206","documentation":"During Tool initialization, smolagents validates the 'inputs' attribute: each input's 'type' must be either a string (e.g. 'string') or a list of strings. If type is any other Python type (int, dict, None, etc.), a TypeError is raised naming the offending type. This guards downstream JSON-schema generation for the LLM.","triggerScenarios":"Defining a Tool subclass (or @tool-decorated function's inputs dict) where an input entry has 'type': None, 'type': 3, or 'type': {'type': 'string'} instead of 'type': 'string' or 'type': ['string', 'integer'].","commonSituations":"Copying Gradio API descriptions or JSON schemas verbatim into inputs, forgetting quotes around type names, or using numpy/python types instead of string literals.","solutions":["Set the input's type to a string literal like \"type\": \"string\"","If multiple types are allowed, use a list of strings: \"type\": [\"string\", \"integer\"]","Ensure every entry in self.inputs has a 'type' key at all (a missing key raises KeyError instead)"],"exampleFix":"# before\nself.inputs = {\"text\": {\"type\": None, \"description\": \"...\"}}\n# after\nself.inputs = {\"text\": {\"type\": \"string\", \"description\": \"...\"}}","handlingStrategy":"validation","validationCode":"def valid_input_schema(inputs):\n    for name, spec in inputs.items():\n        t = spec.get(\"type\")\n        if not isinstance(t, str) and not (isinstance(t, list) and all(isinstance(x, str) for x in t)):\n            return False\n    return True\n\nassert valid_input_schema(MyTool.inputs)","typeGuard":"from typing import Union\ndef is_valid_type(t: object) -> bool:\n    return isinstance(t, str) or (isinstance(t, list) and t and all(isinstance(x, str) for x in t))","tryCatchPattern":null,"preventionTips":["Always write input types as string literals ('string', 'integer', ...), never Python type objects","Add a unit test that instantiates your Tool subclass so validation runs in CI","Keep a canonical example inputs dict and copy from it"],"tags":["smolagents","tool","inputs","type-validation"],"backgroundTag":"invalid-tool-input-schema","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}