ComposioHQ/composio · error · ValidationError

{context}: slug must only contain alphanumeric characters, u

Error message

{context}: slug must only contain alphanumeric characters, underscores, and hyphens

What it means

Raised when a custom tool/toolkit slug contains characters outside [A-Za-z0-9_-]. Slugs are embedded in routed tool names sent to the backend, so they must match the strict SLUG_REGEX.

Source

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

        Experimental as SessionCreateResponseExperimental,
    )
    from composio_client.types.tool_router.session_retrieve_response import (
        Experimental as SessionRetrieveResponseExperimental,
    )


# ────────────────────────────────────────────────────────────────
# Slug validation helpers
# ────────────────────────────────────────────────────────────────


def _validate_slug(slug: str, context: str) -> str:
    """Validate a custom tool or toolkit slug."""
    if not slug:
        raise ValidationError(f"{context}: slug is required")

    if not SLUG_REGEX.match(slug):
        raise ValidationError(
            f"{context}: slug must only contain alphanumeric characters, "
            f"underscores, and hyphens"
        )

    upper = slug.upper()
    if upper.startswith("LOCAL_"):
        raise ValidationError(
            f'{context}: slug must not start with "LOCAL_" — '
            f"this prefix is reserved for internal routing."
        )
    if upper.startswith("COMPOSIO_"):
        raise ValidationError(
            f'{context}: slug must not start with "COMPOSIO_" — '
            f"this prefix is reserved for Composio meta tools."
        )

    return slug

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Sanitize the slug to only alphanumeric, underscore, and hyphen characters (e.g. re.sub(r'[^a-zA-Z0-9_-]', '_', slug))
  2. Replace spaces with underscores or hyphens manually before creating the tool
  3. If generating from arbitrary text, use a proper slugify helper and verify against ^[a-zA-Z0-9_-]+$ before passing it in

Example fix

# before
Tool(slug="search.docs", ...)

# after
import re
slug = re.sub(r"[^a-zA-Z0-9_-]", "_", "search.docs")  # 'search_docs'
Tool(slug=slug, ...)
Defensive patterns

Strategy: validation

Validate before calling

import re
def slugify(s: str) -> str:
    return re.sub(r"[^a-zA-Z0-9_-]", "_", s.strip()) or "tool"

Type guard

def is_valid_slug(slug: str) -> bool:
    import re
    return bool(re.fullmatch(r"[a-zA-Z0-9_-]+", slug))

Try / catch

try:
    Tool(slug=slug, ...)
except ValidationError:
    Tool(slug=slugify(slug), ...)

Prevention

When it happens

Trigger: Passing a slug with spaces, dots, slashes, unicode, or other symbols, e.g. slug='search.docs' or slug='search docs'; auto-derived slugs from docstrings or filenames containing invalid characters.

Common situations: Slugifying titles with a function that allows dots or spaces; using paths or UUIDs as slugs; non-ASCII tool names from localization.

Related errors


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