ComposioHQ/composio · error · InvalidSchemaError

Tool input schema property names produce a duplicate Python

Error message

Tool input schema property names produce a duplicate Python parameter alias {safe_name!r}

What it means

alias_tool_input_schema rewrites property names into valid Python identifiers; when two distinct original names collapse to the same safe alias (e.g. "user-id" and "user_id" both become user_id), the collision is rejected with InvalidSchemaError because the generated function signature would be ambiguous.

Source

Thrown at python/composio/utils/shared.py:296

            on_unresolved="sentinel",
        ),
    )
    schema_params, aliases = _alias_schema_properties(aliased_schema)
    return ToolSchemaAliases(schema=schema_params, aliases=aliases)


def _alias_schema_properties(schema: t.Dict[str, t.Any]) -> t.Tuple[dict, dict]:
    properties = schema.get("properties")
    if not isinstance(properties, dict):
        return schema, {}

    aliases: t.Dict[str, t.Any] = {}
    aliased_properties: t.Dict[str, t.Any] = {}

    for original_name, property_schema in properties.items():
        safe_name = _make_python_identifier(original_name)
        if safe_name in aliased_properties:
            raise InvalidSchemaError(
                "Tool input schema property names produce a duplicate Python "
                f"parameter alias {safe_name!r}"
            )

        nested_object_aliases: t.Dict[str, t.Any] = {}
        nested_array_aliases: t.Dict[str, t.Any] = {}
        if isinstance(property_schema, dict):
            property_schema, nested_object_aliases = _alias_nested_object_schema(
                property_schema
            )
            property_schema, nested_array_aliases = _alias_nested_array_schema(
                property_schema
            )

        aliased_properties[safe_name] = property_schema
        if safe_name != original_name or nested_object_aliases or nested_array_aliases:
            aliases[safe_name] = original_name
        if nested_object_aliases:

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Rename one of the colliding properties in the tool schema so their sanitized forms differ (e.g. "user-id" → "user_id_v2")
  2. Remove the redundant duplicate property if both spellings mean the same thing
  3. If the schema is backend-managed, report the collision — it must be fixed at the source

Example fix

# before
{"properties": {"auth-token": {...}, "auth_token": {...}}}
# after
{"properties": {"auth_token": {...}, "auth_token_v2": {...}}}
Defensive patterns

Strategy: validation

Validate before calling

from composio.utils.shared import _make_python_identifier
def no_alias_collisions(schema):
    props = schema.get("properties", {})
    seen = set()
    for name in props:
        alias = _make_python_identifier(name)
        if alias in seen: return False
        seen.add(alias)
    return True

Try / catch

try:
    alias_tool_input_schema(schema)
except InvalidSchemaError as e:
    if "duplicate Python parameter alias" in str(e):
        schema = rename_colliding_properties(schema)

Prevention

When it happens

Trigger: A tool schema with properties like "auth-token" and "auth_token", or "class" and "Class_", or names differing only in punctuation/case that _make_python_identifier normalizes identically. Raised while building the aliased schema/signature, before any call happens.

Common situations: Backend tool definitions mixing naming conventions; recently added properties that collide with existing ones after normalization; specs generated from APIs with inconsistent param naming (kebab + snake variants of the same param).

Related errors


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