{"record":{"id":"fab26328430d0491","repo":"ComposioHQ/composio","slug":"context-slug-tool-slug-is-too-long-with-pr","errorCode":null,"errorMessage":"{context}: slug \"{tool_slug}\" is too long. With prefix \"{prefix}\", the final slug would be {final_length} characters (max {MAX_SLUG_LENGTH}). Shorten the slug to at most {available} characters.","messagePattern":"(.+?): slug \"(.+?)\" is too long\\. With prefix \"(.+?)\", the final slug would be (.+?) characters \\(max (.+?)\\)\\. Shorten the slug to at most (.+?) characters\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"python/composio/core/models/custom_tool.py","lineNumber":125,"sourceCode":"def _compute_final_slug_length(tool_slug: str, toolkit_slug: t.Optional[str]) -> int:\n    \"\"\"Compute the final slug length: LOCAL_[TOOLKIT_]SLUG.\"\"\"\n    length = len(LOCAL_TOOL_PREFIX) + len(tool_slug)\n    if toolkit_slug:\n        length += len(toolkit_slug) + 1  # +1 for underscore separator\n    return length\n\n\ndef _validate_slug_length(\n    tool_slug: str, toolkit_slug: t.Optional[str], context: str\n) -> None:\n    \"\"\"Validate that the final slug won't exceed the max length.\"\"\"\n    final_length = _compute_final_slug_length(tool_slug, toolkit_slug)\n    if final_length > MAX_SLUG_LENGTH:\n        prefix = LOCAL_TOOL_PREFIX + (\n            f\"{toolkit_slug.upper()}_\" if toolkit_slug else \"\"\n        )\n        available = MAX_SLUG_LENGTH - len(prefix)\n        raise ValidationError(\n            f'{context}: slug \"{tool_slug}\" is too long. '\n            f'With prefix \"{prefix}\", the final slug would be {final_length} '\n            f\"characters (max {MAX_SLUG_LENGTH}). \"\n            f\"Shorten the slug to at most {available} characters.\"\n        )\n\n\ndef _build_final_slug(tool_slug: str, toolkit_slug: t.Optional[str] = None) -> str:\n    \"\"\"Build the final slug: LOCAL_[TOOLKIT_]SLUG.\"\"\"\n    upper = tool_slug.upper()\n    if toolkit_slug:\n        return f\"{LOCAL_TOOL_PREFIX}{toolkit_slug.upper()}_{upper}\"\n    return f\"{LOCAL_TOOL_PREFIX}{upper}\"\n\n\ndef _get_input_json_schema(model: t.Type[BaseModel]) -> t.Dict[str, t.Any]:\n    \"\"\"Convert a Pydantic model class to a JSON Schema dict suitable for the backend.\"\"\"\n    full_schema = model.model_json_schema()","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/python/composio/core/models/custom_tool.py#L107-L143","documentation":"Raised when a custom tool's slug, after Composio prepends the LOCAL_ + TOOLKIT_ routing prefix, would exceed MAX_SLUG_LENGTH. The final routed name must fit the length cap, so the user slug alone must be short enough.","triggerScenarios":"Creating a tool with a very long slug (and/or a long toolkit slug) such that len('LOCAL_<TOOLKIT>_<slug>') > MAX_SLUG_LENGTH, via the @tool decorator, Tool(), or toolkit.tool(...).","commonSituations":"Auto-generating slugs from verbose function or docstring titles; long toolkit names eating the budget; machine-generated descriptive slugs from LLM pipelines.","solutions":["Shorten the tool slug to the reported `available` character count (the error message tells you the exact budget)","Shorten the toolkit slug too — it reduces the prefix length and frees characters for the tool slug","When generating slugs programmatically, truncate to a safe bound before tool creation"],"exampleFix":"# before\n@tool(slug=\"perform_advanced_semantic_search_across_all_connected_user_documents\")\n\n# after\n@tool(slug=\"semantic_doc_search\")","handlingStrategy":"validation","validationCode":"from composio.core.models.custom_tool import MAX_SLUG_LENGTH, LOCAL_TOOL_PREFIX\ndef fits(slug: str, toolkit_slug: str = \"\") -> bool:\n    prefix = LOCAL_TOOL_PREFIX + (f\"{toolkit_slug.upper()}_\" if toolkit_slug else \"\")\n    return len(prefix) + len(slug) <= MAX_SLUG_LENGTH\ndef clip(slug: str, toolkit_slug: str = \"\") -> str:\n    prefix = LOCAL_TOOL_PREFIX + (f\"{toolkit_slug.upper()}_\" if toolkit_slug else \"\")\n    return slug[: MAX_SLUG_LENGTH - len(prefix)]","typeGuard":"def slug_fits(slug: str, toolkit_slug: str) -> bool:\n    prefix = \"LOCAL_\" + (toolkit_slug.upper() + \"_\" if toolkit_slug else \"\")\n    return len(prefix + slug) <= 64  # verify MAX_SLUG_LENGTH for your version","tryCatchPattern":"try:\n    Tool(slug=slug, ...)\nexcept ValidationError:\n    Tool(slug=slug[:40], ...)","preventionTips":["Keep tool slugs short (< 40 chars) and toolkit slugs concise","Truncate auto-generated slugs before registration","Read the available budget from the error message when it fires"],"tags":["python","custom-tools","slug-validation","length-limit"],"backgroundTag":"identifier-too-long","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}