{"record":{"id":"2de25a563d818059","repo":"run-llama/llama_index","slug":"tool-name-cannot-be-none","errorCode":null,"errorMessage":"Tool name cannot be None","messagePattern":"Tool name cannot be None","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/tools/tool_spec/load_and_search/base.py","lineNumber":65,"sourceCode":"    \"\"\"\n\n    def __init__(\n        self,\n        tool: FunctionTool,\n        index_cls: Type[BaseIndex],\n        index_kwargs: Dict,\n        metadata: ToolMetadata,\n        index: Optional[BaseIndex] = None,\n    ) -> None:\n        \"\"\"Init params.\"\"\"\n        self._index_cls = index_cls\n        self._index_kwargs = index_kwargs\n        self._index = index\n        self._metadata = metadata\n        self._tool = tool\n\n        if self._metadata.name is None:\n            raise ValueError(\"Tool name cannot be None\")\n        self.spec_functions = [\n            self._metadata.name,\n            f\"read_{self._metadata.name}\",\n        ]\n        self._tool_list = [\n            FunctionTool.from_defaults(\n                fn=self.load,\n                name=self._metadata.name,\n                description=self.loader_prompt.format(\n                    self._metadata.name, self._metadata.description\n                ),\n                fn_schema=self._metadata.fn_schema,\n            ),\n            FunctionTool.from_defaults(\n                fn=self.read,\n                name=str(f\"read_{self._metadata.name}\"),\n                description=self.reader_prompt.format(metadata.name),\n                fn_schema=create_schema_from_function(\"ReadData\", self.read),","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/tools/tool_spec/load_and_search/base.py#L47-L83","documentation":"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.","triggerScenarios":"Constructing LoadAndSearchToolSpec(tool=..., index_cls=..., index_kwargs=..., metadata=ToolMetadata(description='...')) with no name; or building ToolMetadata programmatically where name was never set.","commonSituations":"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.","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."],"exampleFix":"# before\nspec = LoadAndSearchToolSpec(\n    tool=doc_tool, index_cls=VectorStoreIndex, index_kwargs={},\n    metadata=ToolMetadata(description='searches docs'),  # name is None\n)\n\n# after\nspec = LoadAndSearchToolSpec(\n    tool=doc_tool, index_cls=VectorStoreIndex, index_kwargs={},\n    metadata=ToolMetadata(name='doc_search', description='searches docs'),\n)","handlingStrategy":"validation","validationCode":"from llama_index.core.tools import ToolMetadata\n\ndef make_load_search_spec(tool, index_cls, index_kwargs):\n    meta = tool.metadata if hasattr(tool, 'metadata') else None\n    name = getattr(meta, 'name', None) or 'doc_tool'\n    return ToolMetadata(name=name, description=meta.description if meta else '')","typeGuard":"def has_tool_name(metadata) -> bool:\n    return getattr(metadata, 'name', None) is not None","tryCatchPattern":"try:\n    spec = LoadAndSearchToolSpec(tool=t, index_cls=VectorStoreIndex,\n                                index_kwargs={}, metadata=meta)\nexcept ValueError as e:\n    if 'Tool name cannot be None' in str(e):\n        meta = meta.model_copy(update={'name': 'doc_tool'})\n        spec = LoadAndSearchToolSpec(tool=t, index_cls=VectorStoreIndex,\n                                    index_kwargs={}, metadata=meta)\n    else:\n        raise","preventionTips":["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."],"tags":["tool-metadata","load-and-search","validation","value-error"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}