ComposioHQ/composio · error · ValidationError
{context}: description is required
Error message
{context}: description is required What it means
Raised when creating a custom tool with an empty description. Descriptions are what LLMs use to decide when to call the tool, so Composio requires them.
Source
Thrown at python/composio/core/models/custom_tool.py:178
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."
)
except ImportError:
passView on GitHub (pinned to 64b1b85502)
Solutions
- Add a clear description parameter or a docstring: for @tool-decorated functions the function docstring becomes the description
- Check that docstrings survive your build (avoid -OO / aggressive minifiers) if you rely on implicit descriptions
- Validate generated tool definitions contain a non-empty description before registration
Example fix
# before
def search(q: str):
pass # no docstring
# after
def search(q: str):
"""Search the user's connected documents for a query."" Defensive patterns
Strategy: validation
Validate before calling
if not description:
description = (fn.__doc__ or "").strip() or f"Execute {fn.__name__}."
assert description, "description required" Type guard
def has_description(desc: str | None) -> bool:
return bool(desc and desc.strip()) Try / catch
try:
Tool(description=description, ...)
except ValidationError:
Tool(description=fn.__doc__ or f"Executes {fn.__name__}.", ...) Prevention
- Write a docstring on every tool function — it becomes the description
- Never build with python -OO if you rely on docstrings
- Validate generated tool configs contain descriptions in CI
When it happens
Trigger: Calling Tool(...) or the @tool decorator without a docstring-derived description, or with description="".
Common situations: Forgetting the docstring on a decorated function and not passing description explicitly; stripping docstrings in production builds or with python -OO; config-driven tool definitions missing the description key.
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
- {context}: name is required
- Could not determine a home directory to store the Composio c
- Cache directory {directory} is not writable please provide a
- module {__name__!r} has no attribute {name!r}
- Failed to upload to S3: {_sanitize_url_for_logging(url)}. Er
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/61fa7e8795d98fee.
Report an issue: GitHub.