deepset-ai/haystack · error · ValueError
Function '{function.__name__}': parameter '{param_name}' doe
Error message
Function '{function.__name__}': parameter '{param_name}' does not have a type hint. What it means
create_tool_from_function builds a tool schema from a plain function's signature; every parameter (except State-typed ones and Callables) must carry a type annotation, because a Pydantic model cannot be generated without one. If any parameter's annotation is empty (param.empty), a ValueError is raised naming the function and parameter.
Source
Thrown at haystack/tools/from_function.py:151
tool_description = description if description is not None else (function.__doc__ or "")
signature = inspect.signature(function)
# collect fields (types and defaults) and descriptions from function parameters
fields: dict[str, Any] = {}
descriptions = {}
for param_name, param in signature.parameters.items():
# Skip adding parameter names that will be passed to the tool from State
if inputs_from_state and param_name in inputs_from_state.values():
continue
# Skip State-typed parameters (including Optional[State]) - Agent tool execution injects them at runtime
if _unwrap_optional(param.annotation) is State:
continue
if param.annotation is param.empty:
raise ValueError(f"Function '{function.__name__}': parameter '{param_name}' does not have a type hint.")
# Skip Callable types since Pydantic cannot generate JSON schemas for them
if _contains_callable_type(param.annotation):
continue
# if the parameter has not a default value, Pydantic requires an Ellipsis (...)
# to explicitly indicate that the parameter is required
default = param.default if param.default is not param.empty else ...
fields[param_name] = (param.annotation, default)
if hasattr(param.annotation, "__metadata__"):
descriptions[param_name] = param.annotation.__metadata__[0]
# create Pydantic model and generate JSON schema
try:
model = create_model(function.__name__, **fields)
schema = model.model_json_schema()
except Exception as e:View on GitHub (pinned to e318778c9b)
Solutions
- Add a type annotation to the parameter named in the message
- Annotate every parameter of the function you pass to @tool / create_tool_from_function
- If the parameter is Agent State, annotate it as State (it is then skipped)
- If the parameter should not be exposed to the LLM, remove it from the signature or give it a module-level constant default outside the tool function
Example fix
// before
def search(query, limit=5):
...
// after
def search(query: str, limit: int = 5) -> dict:
... Defensive patterns
Strategy: validation
Validate before calling
import inspect
def validate_tool_function(fn) -> list[str]:
return [
p.name
for p in inspect.signature(fn).parameters.values()
if p.annotation is inspect.Parameter.empty
]
missing = validate_tool_function(search)
assert not missing, f"Parameters missing type hints: {missing}" Type guard
import inspect
def is_fully_annotated(fn) -> bool:
return all(
p.annotation is not inspect.Parameter.empty
for p in inspect.signature(fn).parameters.values()
) Try / catch
try:
tool = create_tool_from_function(search)
except ValueError as e:
# message names the offending parameter
raise TypeError(f"Fix tool function signature: {e}") from e Prevention
- Fully annotate every tool function's parameters and return type
- Run mypy/ruff (ANN rules) so un-annotated functions fail CI before tool creation
- Annotate Agent-injected params explicitly as State so they're skipped correctly
When it happens
Trigger: @tool or create_tool_from_function(fn) where fn has an un-annotated parameter, e.g. def search(query, limit=5): ...
Common situations: Quick scripts with loosely typed helpers; migrating older Python code without annotations into tools; forgetting annotations on **kwargs-like helper parameters or defaults-only parameters.
Related errors
- Tool execution requires at least one tool.
- 'dimension' must be a positive integer.
- 'dimension' must be a positive integer.
- LLM evaluator expected input parameter '{param}' but receive
- LLM evaluator expects all input values to be lists but recei
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/a54e6fa6b1af465f.
Report an issue: GitHub.