huggingface/smolagents · error · TypeError
Argument {key} has type '{actual_type}' but should be '{tool
Error message
Argument {key} has type '{actual_type}' but should be '{tool.inputs[key]['type']}' What it means
Raised by smolagents' validate_tool_arguments when an argument passed to a tool does not match the JSON Schema type declared in the tool's inputs definition. It is the library's pre-execution guard so that tool forward() methods receive correctly typed values. Integer values are accepted where 'number' is expected, and 'any' or nullable schemas bypass the check.
Source
Thrown at src/smolagents/tools.py:1402
"""
if isinstance(arguments, dict):
for key, value in arguments.items():
if key not in tool.inputs:
raise ValueError(f"Argument {key} is not in the tool's input schema")
actual_type = _get_json_schema_type(type(value))["type"]
expected_type = tool.inputs[key]["type"]
expected_type_is_nullable = tool.inputs[key].get("nullable", False)
# Type is valid if it matches, is "any", or is null for nullable parameters
if (
(actual_type != expected_type if isinstance(expected_type, str) else actual_type not in expected_type)
and expected_type != "any"
and not (actual_type == "null" and expected_type_is_nullable)
):
if actual_type == "integer" and expected_type == "number":
continue
raise TypeError(f"Argument {key} has type '{actual_type}' but should be '{tool.inputs[key]['type']}'")
for key, schema in tool.inputs.items():
key_is_nullable = schema.get("nullable", False)
if key not in arguments and not key_is_nullable:
raise ValueError(f"Argument {key} is required")
return None
else:
expected_type = list(tool.inputs.values())[0]["type"]
if _get_json_schema_type(type(arguments))["type"] != expected_type and not expected_type == "any":
raise TypeError(f"Argument has type '{type(arguments).__name__}' but should be '{expected_type}'")
__all__ = [
"AUTHORIZED_TYPES",
"Tool",
"tool",
"load_tool",
"launch_gradio_demo",View on GitHub (pinned to 30bb116109)
Solutions
- Fix the arguments to match the declared type (e.g., convert '5' to 5 before calling the tool)
- Adjust the tool's inputs declaration to the type actually received, or set 'type': 'any' / 'nullable': True where appropriate
- If a model keeps emitting wrong types, tighten the tool description or prompt so the model produces correctly typed JSON
- For integer-tolerant float inputs, note ints are allowed for 'number' but not vice versa; cast in your wrapper
Example fix
# before
tool = Tool(name='add', inputs={'a': {'type': 'integer'}}, ...)
tool(a='5') # TypeError
# after
tool(a=int('5'))
# or declare: inputs={'a': {'type': 'any'}} Defensive patterns
Strategy: validation
Validate before calling
import json
def validate_args(tool, arguments):
type_map = {str: 'string', int: 'integer', float: 'number', bool: 'boolean', list: 'array', dict: 'object'}
for key, schema in tool.inputs.items():
if key in arguments and isinstance(schema.get('type'), str):
expected = schema['type']
if expected == 'any':
continue
actual = type_map.get(type(arguments[key]))
if actual and actual != expected and not (actual == 'integer' and expected == 'number'):
raise ValueError(f'{key}: expected {expected}, got {actual}')
return arguments Type guard
def args_match(tool, arguments: dict) -> bool:
tm = {str: 'string', int: 'integer', float: 'number', bool: 'boolean', list: 'array', dict: 'object'}
return all(
s.get('type') == 'any' or tm.get(type(arguments.get(k))) == s.get('type')
or (tm.get(type(arguments.get(k))) == 'integer' and s.get('type') == 'number')
for k, s in tool.inputs.items() if k in arguments
) Try / catch
try:
result = tool(**arguments)
except TypeError as e:
if 'has type' in str(e):
# coerce types from the message and retry, or log and surface to the model
raise Prevention
- Declare tool input types precisely and match them to forward() annotations
- Test each tool with representative argument dicts
- Mark flexible inputs as 'any' or 'nullable' deliberately
When it happens
Trigger: Calling a Tool (or an agent making a tool call) with, e.g., a string '5' where inputs declare {'type': 'integer'}, or a dict where 'array' is declared. Also triggered by argument keys not present in the tool's inputs whose type cannot be validated.
Common situations: LLM models returning numbers as strings, booleans as 'true', or lists as comma-separated strings; mismatch between the tool author's declared input types and what the model actually emits; custom tools with hand-written input schemas that don't match the Python signatures.
Related errors
- Argument has type '{type(arguments).__name__}' but should be
- step_callbacks must be a list or a dict
- Error while parsing tool call from model output: {e}
- If you want to return an answer, please do not perform any o
- You returned multiple final answers. Please return only one
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/c8554309806d8b1e.
Report an issue: GitHub.