deepset-ai/haystack · error · ValueError
The following tool names are not valid: {invalid_tool_names}
Error message
The following tool names are not valid: {invalid_tool_names}. Valid tool names are: {valid_tool_names}. What it means
Raised when names requested for tool selection are not among the names of selectable tools exposed by the Agent's configured Tool/Toolset items. The set difference `requested_names - valid_tool_names` is non-empty, so the library aborts rather than silently selecting a subset.
Source
Thrown at haystack/components/agents/utils.py:146
requested_names = set(names)
items: list[Tool | Toolset] = (
[configured_tools] if isinstance(configured_tools, Toolset) else list(configured_tools)
)
# Resolve the tools each item offers for selection
selectable_per_item: list[tuple[Tool | Toolset, list[Tool]]] = []
for item in items:
selectable = item.get_selectable_tools() if isinstance(item, Toolset) else [item]
selectable_per_item.append((item, selectable))
valid_tool_names = {tool.name for _, selectable in selectable_per_item for tool in selectable}
# A dynamic Toolset may look empty before its catalog is resolved, so emptiness is checked here.
if not valid_tool_names:
raise ValueError("No tools were configured for the Agent at initialization.")
invalid_tool_names = requested_names - valid_tool_names
if invalid_tool_names:
raise ValueError(
f"The following tool names are not valid: {invalid_tool_names}. Valid tool names are: {valid_tool_names}."
)
selected: list[Tool | Toolset] = []
for item, selectable in selectable_per_item:
matched = requested_names & {tool.name for tool in selectable}
if not matched:
continue
run_copy = _spawn_selection_copy(item, matched)
if run_copy is not None:
selected.append(run_copy)
else:
# Select from `selectable`, the list the names were validated against: iterating a dynamic
# Toolset could silently miss tools.
selected.extend(tool for tool in selectable if tool.name in matched)
return selected
View on GitHub (pinned to e318778c9b)
Solutions
- Fix the requested names to match the actual tool names exposed by the configured tools/toolsets.
- Print or log the valid names: the error message includes the set of valid tool names — align to those.
- Ensure the Toolset that owns the referenced tools is included in the Agent's `tools` list.
Example fix
// before agent = Agent(gen, tools=[toolset], tool_names=["web_search"]) // after agent = Agent(gen, tools=[toolset], tool_names=["search_internet"]) # matches toolset tool
Defensive patterns
Strategy: validation
Validate before calling
def validate_tool_names(tools, requested):
valid = set()
for item in tools:
selectable = item.get_selectable_tools() if hasattr(item, "get_selectable_tools") else [item]
valid |= {t.name for t in selectable}
unknown = set(requested) - valid
if unknown:
raise AssertionError(f"Unknown tool names {unknown}; valid: {valid}") Try / catch
try:
agent = Agent(gen, tools=tools, tool_names=names)
except ValueError as e:
if "not valid" in str(e):
logging.error("Tool name typo: %s", e)
raise Prevention
- Derive requested names programmatically from tool objects instead of hardcoding strings.
- Re-check names after renaming any tool.
- Keep tool name constants in one module shared by tool definitions and Agent config.
When it happens
Trigger: Passing a `tool_names` list to Agent/_select_tools containing a typo, a tool belonging to a Toolset that was not configured, or a name from a dynamic Toolset catalog that failed to resolve.
Common situations: Typos in tool names; renaming a tool and forgetting to update the Agent config; referencing tools from a different Toolset than the one wired into the Agent; stale serialized pipeline YAML with old names.
Related errors
- user_prompt must define exactly one message block, found {le
- system_prompt must define exactly one message block, found {
- user_prompt message block must have role 'user', found role
- system_prompt message block must have role 'system', found r
- {prompt_label} must render to exactly one {expected_role.val
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/3957ffde44288eb0.
Report an issue: GitHub.