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

  1. Fix the requested names to match the actual tool names exposed by the configured tools/toolsets.
  2. Print or log the valid names: the error message includes the set of valid tool names — align to those.
  3. 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

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


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/3957ffde44288eb0. Report an issue: GitHub.