run-llama/llama_index · error · ValueError

name is None.

Error message

name is None.

What it means

ToolMetadata.get_name() refuses to return when the name field is None. The name field is Optional in the pydantic model, but most execution paths (tool registration, agent tool-call routing, logging) require a concrete name, so this method fails fast rather than returning None.

Source

Thrown at llama-index-core/llama_index/core/tools/types.py:59

            parameters = {
                k: v
                for k, v in parameters.items()
                if k in ["type", "properties", "required", "definitions", "$defs"]
            }
        return parameters

    @property
    def fn_schema_str(self) -> str:
        """Get fn schema as string."""
        if self.fn_schema is None:
            raise ValueError("fn_schema is None.")
        parameters = self.get_parameters_dict()
        return json.dumps(parameters, ensure_ascii=False)

    def get_name(self) -> str:
        """Get name."""
        if self.name is None:
            raise ValueError("name is None.")
        return self.name

    def _sanitize_name(self, name: Optional[str]) -> Optional[str]:
        """
        Sanitize name to match OpenAI's function name requirements.

        OpenAI requires function names to match ^[a-zA-Z0-9_-]+$.
        Generic Pydantic models like GenericModel[int] contain brackets
        which are not allowed.
        """
        if name is None:
            return None
        return re.sub(r"[^a-zA-Z0-9_-]", "_", name)

    @deprecated(
        "Deprecated in favor of `to_openai_tool`, which should be used instead."
    )
    def to_openai_function(self) -> Dict[str, Any]:

View on GitHub (pinned to afd0fef371)

Solutions

  1. Always set name explicitly: ToolMetadata(name='search_docs', description='...').
  2. When creating tools from config, validate required keys ('name', 'description') before constructing ToolMetadata.
  3. Use FunctionTool.from_defaults(fn=fn, name='...') which forwards the name into metadata.

Example fix

# before
 tool = FunctionTool.from_defaults(fn=search, description='search docs')
 agent_tool_name = tool.metadata.get_name()  # ValueError

# after
 tool = FunctionTool.from_defaults(fn=search, name='search_docs', description='search docs')
 agent_tool_name = tool.metadata.get_name()
Defensive patterns

Strategy: validation

Validate before calling

def require_tool_name(metadata):
    if getattr(metadata, 'name', None) is None:
        raise ValueError('ToolMetadata.name is required for agent registration')
    return metadata.name

Type guard

def has_tool_name(metadata) -> bool:
    return getattr(metadata, 'name', None) is not None

Try / catch

try:
    name = tool.metadata.get_name()
except ValueError as e:
    if 'name is None' in str(e):
        name = getattr(tool.fn, '__name__', 'anonymous_tool')
        tool.metadata = tool.metadata.model_copy(update={'name': name})
    else:
        raise

Prevention

When it happens

Trigger: Calling tool.metadata.get_name() on metadata constructed without a name, e.g. ToolMetadata(description='...'). Frequently triggered indirectly by agent frameworks that call get_name() on every tool in a list.

Common situations: Custom tools built with ToolMetadata where only description was supplied; programmatic tool creation from config dicts where the 'name' key was misspelled; older code upgrading to a LlamaIndex version that added this strict check.

Related errors


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