deepset-ai/haystack · error · ValueError
Invalid search_tool_parameters_description keys: {invalid_ke
Error message
Invalid search_tool_parameters_description keys: {invalid_keys}. Valid keys are: {self._VALID_SEARCH_TOOL_PARAMS} What it means
SearchableToolset accepts an optional search_tool_parameters_description dict whose keys are restricted to a fixed whitelist (_VALID_SEARCH_TOOL_PARAMS). Passing keys outside that set raises ValueError listing the invalid keys and the valid ones.
Source
Thrown at haystack/tools/searchable_toolset.py:111
:param search_tool_name: Custom name for the bootstrap search tool. Default is "search_tools".
:param search_tool_description: Custom description for the bootstrap search tool. If not provided, uses a
default description.
:param search_tool_parameters_description: Custom descriptions for the bootstrap search tool's parameters.
Keys must be a subset of `{"tool_keywords", "k"}`.
Example: `{"tool_keywords": "Keywords to find tools, e.g. 'email send'"}`
"""
valid_catalog = isinstance(catalog, Toolset) or (
isinstance(catalog, list) and all(isinstance(item, (Tool, Toolset)) for item in catalog)
)
if not valid_catalog:
raise TypeError(
f"Invalid catalog type: {type(catalog)}. Expected Tool, Toolset, or list of Tools and/or Toolsets."
)
if search_tool_parameters_description is not None:
invalid_keys = set(search_tool_parameters_description.keys()) - self._VALID_SEARCH_TOOL_PARAMS
if invalid_keys:
raise ValueError(
f"Invalid search_tool_parameters_description keys: {invalid_keys}. "
f"Valid keys are: {self._VALID_SEARCH_TOOL_PARAMS}"
)
# Store raw catalog; flattening is deferred to warm_up() so that lazy toolsets
# (e.g. MCPToolset with eager_connect=False) can connect first.
self._raw_catalog: "ToolsType" = catalog
self._catalog: list[Tool] = []
self._top_k = top_k
self._search_threshold = search_threshold
self._search_tool_name = search_tool_name
self._search_tool_description = search_tool_description
self._search_tool_parameters_description = search_tool_parameters_description
# Runtime state (initialized in warm_up)
self._discovered_tools: dict[str, Tool] = {}
self._bootstrap_tool: Tool | None = NoneView on GitHub (pinned to e318778c9b)
Solutions
- Use only keys in SearchableToolset._VALID_SEARCH_TOOL_PARAMS
- Fix typos in the dict keys (the error message lists the valid set)
- Check the SearchableToolset docstring/API docs for the accepted parameter-description keys
Example fix
// before
SearchableToolset(catalog=tools, search_tool_parameters_description={"description": "...", "keywords_hint": "..."})
// after
SearchableToolset(catalog=tools, search_tool_parameters_description={"description": "..."}) Defensive patterns
Strategy: validation
Validate before calling
VALID = SearchableToolset._VALID_SEARCH_TOOL_PARAMS
def clean_param_description(d: dict | None) -> dict | None:
if d is None:
return None
invalid = set(d) - VALID
if invalid:
raise ValueError(f"Invalid keys {invalid}; valid: {VALID}")
return d
SearchableToolset(catalog=tools, search_tool_parameters_description=clean_param_description(desc)) Type guard
def has_only_valid_keys(d: dict | None) -> bool:
return d is None or set(d) <= set(SearchableToolset._VALID_SEARCH_TOOL_PARAMS) Try / catch
try:
ts = SearchableToolset(catalog=tools, search_tool_parameters_description=desc)
except ValueError as e:
logger.warning("Dropping invalid search_tool params: %s", e)
ts = SearchableToolset(catalog=tools) Prevention
- Copy keys directly from SearchableToolset._VALID_SEARCH_TOOL_PARAMS rather than typing them
- Centralize toolset config in one validated dict
- Pin the haystack version so accepted keys don't drift unexpectedly
When it happens
Trigger: SearchableToolset(catalog=..., search_tool_parameters_description={"desc": "..."}) or any misspelled/unexpected key not in _VALID_SEARCH_TOOL_PARAMS.
Common situations: Typo in a key name (e.g. 'descriptions' vs 'description'); guessing parameter names instead of checking the class constant; copying config from a different toolset version with different keys.
Related errors
- Hook of type '{type(h).__name__}' is registered under hook p
- 'dimension' must be a positive integer.
- 'dimension' must be a positive integer.
- 'chat_generators' must be a non-empty list
- required_variables must not be empty. Set it to '*' to requi
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/dee40e43e8da5ec4.
Report an issue: GitHub.