run-llama/llama_index · error · ValueError
Tool name cannot be None
Error message
Tool name cannot be None
What it means
LoadAndSearchToolSpec's __init__ requires ToolMetadata with a non-None name because it derives its two function names ('<name>' and 'read_<name>') from it. Passing ToolMetadata(name=None) (the default when name is omitted in some constructors) fails immediately at construction time.
Source
Thrown at llama-index-core/llama_index/core/tools/tool_spec/load_and_search/base.py:65
"""
def __init__(
self,
tool: FunctionTool,
index_cls: Type[BaseIndex],
index_kwargs: Dict,
metadata: ToolMetadata,
index: Optional[BaseIndex] = None,
) -> None:
"""Init params."""
self._index_cls = index_cls
self._index_kwargs = index_kwargs
self._index = index
self._metadata = metadata
self._tool = tool
if self._metadata.name is None:
raise ValueError("Tool name cannot be None")
self.spec_functions = [
self._metadata.name,
f"read_{self._metadata.name}",
]
self._tool_list = [
FunctionTool.from_defaults(
fn=self.load,
name=self._metadata.name,
description=self.loader_prompt.format(
self._metadata.name, self._metadata.description
),
fn_schema=self._metadata.fn_schema,
),
FunctionTool.from_defaults(
fn=self.read,
name=str(f"read_{self._metadata.name}"),
description=self.reader_prompt.format(metadata.name),
fn_schema=create_schema_from_function("ReadData", self.read),View on GitHub (pinned to afd0fef371)
Solutions
- Set an explicit name: metadata = ToolMetadata(name='my_doc_tool', description='...').
- If wrapping another tool, reuse its name: ToolMetadata(name=inner_tool.metadata.name, ...).
- Sanitize the name to ^[a-zA-Z0-9_-]+$ since it is also used in generated function names.
Example fix
# before
spec = LoadAndSearchToolSpec(
tool=doc_tool, index_cls=VectorStoreIndex, index_kwargs={},
metadata=ToolMetadata(description='searches docs'), # name is None
)
# after
spec = LoadAndSearchToolSpec(
tool=doc_tool, index_cls=VectorStoreIndex, index_kwargs={},
metadata=ToolMetadata(name='doc_search', description='searches docs'),
) Defensive patterns
Strategy: validation
Validate before calling
from llama_index.core.tools import ToolMetadata
def make_load_search_spec(tool, index_cls, index_kwargs):
meta = tool.metadata if hasattr(tool, 'metadata') else None
name = getattr(meta, 'name', None) or 'doc_tool'
return ToolMetadata(name=name, description=meta.description if meta else '') Type guard
def has_tool_name(metadata) -> bool:
return getattr(metadata, 'name', None) is not None Try / catch
try:
spec = LoadAndSearchToolSpec(tool=t, index_cls=VectorStoreIndex,
index_kwargs={}, metadata=meta)
except ValueError as e:
if 'Tool name cannot be None' in str(e):
meta = meta.model_copy(update={'name': 'doc_tool'})
spec = LoadAndSearchToolSpec(tool=t, index_cls=VectorStoreIndex,
index_kwargs={}, metadata=meta)
else:
raise Prevention
- Always pass name= to ToolMetadata when building load-and-search specs.
- Reuse the inner tool's name when wrapping: name=inner.metadata.name.
- Validate config dicts contain 'name' before constructing ToolMetadata.
When it happens
Trigger: Constructing LoadAndSearchToolSpec(tool=..., index_cls=..., index_kwargs=..., metadata=ToolMetadata(description='...')) with no name; or building ToolMetadata programmatically where name was never set.
Common situations: Creating a load-and-search tool over a document tool (e.g. from llama_index.core.tools.tool_spec.load_and_search) and forgetting that ToolMetadata.name is Optional in the type system but mandatory for this spec.
Related errors
- spec_functions must be of type: List[Union[str, Tuple[str, s
- fn_schema is None.
- name is None.
- Tool description exceeds maximum length of 1024 characters.
- Cannot provide both content and blocks.
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/2de25a563d818059.
Report an issue: GitHub.