ComposioHQ/composio · error · ValidationError

{context}: name is required

Error message

{context}: name is required

What it means

Raised when creating a custom tool with an empty name. The display name is a required field for tool registration and is surfaced to LLMs as the tool label.

Source

Thrown at python/composio/core/models/custom_tool.py:176

def _create_tool(
    slug: str,
    *,
    name: str,
    description: str,
    input_params: t.Type[BaseModel],
    execute: CustomToolExecuteFn,
    extends_toolkit: t.Optional[str] = None,
    output_params: t.Optional[t.Type[BaseModel]] = None,
    preload: t.Optional[bool] = None,
) -> CustomTool:
    """Internal: create and validate a CustomTool."""
    context = "experimental.tool"

    _validate_slug(slug, context)

    if not name:
        raise ValidationError(f"{context}: name is required")
    if not description:
        raise ValidationError(f"{context}: description is required")

    if not isinstance(input_params, type) or not issubclass(input_params, BaseModel):
        raise ValidationError(
            f"{context}: input_params must be a Pydantic BaseModel subclass. "
            f"Tool input parameters are always an object with named properties."
        )

    try:
        from pydantic import RootModel

        if issubclass(input_params, RootModel):
            raise ValidationError(
                f"{context}: input_params must be a regular BaseModel with named fields, "
                f"not a RootModel. Tool input parameters are always an object with "
                f"named properties."
            )

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Provide an explicit non-empty name, e.g. name='Search documentation'
  2. When generating tools from functions, default name to fn.__name__.replace('_', ' ').title() before creation
  3. Validate tool definition dicts/configs before passing them to Tool(...)

Example fix

# before
Tool(slug="search", name="", description="Search", input_params=P, callable=fn)

# after
Tool(slug="search", name="Search", description="Search", input_params=P, callable=fn)
Defensive patterns

Strategy: validation

Validate before calling

if not name:
    name = getattr(fn, "__name__", "tool").replace("_", " ").title()
assert name, "tool name required"

Type guard

def has_name(name: str | None) -> bool:
    return bool(name and name.strip())

Try / catch

try:
    Tool(name=name, ...)
except ValidationError:
    Tool(name=fn.__name__.replace("_", " ").title(), ...)

Prevention

When it happens

Trigger: Calling Tool(...) (or the @tool decorator / _create_tool path) with name="" or a name that ends up empty after defaults are applied.

Common situations: Omitting name expecting it to default to the function name; passing name=None where the signature doesn't default it; data-driven tool definitions where a name field is missing in the source dict/config.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/d889da188b85b2a1. Report an issue: GitHub.