run-llama/llama_index · error · ValueError

Tool name must be set

Error message

Tool name must be set

What it means

SimpleQueryToolNodeMapping._add_object requires tool.metadata.name to be a non-None string because the name is the dict key mapping node back to tool. QueryEngineTool metadata can end up with name=None when constructed with a partial/empty ToolMetadata, and adding it raises ValueError('Tool name must be set'). Note this triggers on add (from_objects), not at tool construction.

Source

Thrown at llama-index-core/llama_index/core/objects/tool_node_mapping.py:143

    """Simple query tool mapping."""

    def __init__(self, objs: Optional[Sequence[QueryEngineTool]] = None) -> None:
        objs = objs or []
        self._tools = {tool.metadata.name: tool for tool in objs}

    def validate_object(self, obj: QueryEngineTool) -> None:
        if not isinstance(obj, QueryEngineTool):
            raise ValueError(f"Object must be of type {QueryEngineTool}")

    @classmethod
    def from_objects(
        cls, objs: Sequence[QueryEngineTool], *args: Any, **kwargs: Any
    ) -> "BaseObjectNodeMapping":
        return cls(objs)

    def _add_object(self, tool: QueryEngineTool) -> None:
        if tool.metadata.name is None:
            raise ValueError("Tool name must be set")
        self._tools[tool.metadata.name] = tool

    def to_node(self, obj: QueryEngineTool) -> TextNode:
        """To node."""
        return convert_tool_to_node(obj)

    def _from_node(self, node: BaseNode) -> QueryEngineTool:
        """From node."""
        if node.metadata is None:
            raise ValueError("Metadata must be set")
        return self._tools[node.metadata["name"]]

View on GitHub (pinned to afd0fef371)

Solutions

  1. Always pass an explicit name: ToolMetadata(name="my_index", description="...")
  2. Validate before adding: `if not tool.metadata.name: raise ...` in your tool factory
  3. Generate deterministic names programmatically (e.g. from the index identifier) when building many tools in a loop

Example fix

# before
tool = QueryEngineTool.from_defaults(query_engine=qe, metadata=ToolMetadata(description="city facts"))
mapping = SimpleQueryToolNodeMapping.from_objects([tool])  # ValueError: Tool name must be set

# after
tool = QueryEngineTool.from_defaults(query_engine=qe, metadata=ToolMetadata(name="city_facts", description="city facts"))
mapping = SimpleQueryToolNodeMapping.from_objects([tool])
Defensive patterns

Strategy: validation

Validate before calling

for tool in tools:
    if not getattr(tool.metadata, "name", None):
        raise ValueError(f"tool has no name: {tool!r}; set ToolMetadata(name=...)")
mapping = SimpleQueryToolNodeMapping.from_objects(tools)

Type guard

def tool_has_name(tool) -> bool:
    return bool(getattr(getattr(tool, "metadata", None), "name", None))

Try / catch

try:
    mapping.add_object(tool)  # or from_objects
except ValueError as e:
    if "Tool name must be set" in str(e):
        tool.metadata.name = generated_unique_name(tool)
        mapping.add_object(tool)
    else:
        raise

Prevention

When it happens

Trigger: SimpleQueryToolNodeMapping.from_objects([tool]) or obj_index.add_object(tool) where tool was built with ToolMetadata(description=...) only, or QueryEngineTool.from_defaults called without metadata/name so a default None leaked through.

Common situations: Creating QueryEngineTool with only a description; programmatic tool generation where the name field was forgotten; older llama-index versions allowing None names more permissively.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/cdf8c54c05b9e2b6. Report an issue: GitHub.