ComposioHQ/composio · error · ValueError

Dynamic-key schema reference {reference!r} does not target a

Error message

Dynamic-key schema reference {reference!r} does not target a schema

What it means

The local $ref resolved successfully but pointed at something that is not a schema — not a dict and not a boolean (e.g. a string, number, or array of values). Dynamic-key references must target JSON Schema nodes, so _check_dynamic_references raises ValueError at construction time.

Source

Thrown at python/composio/utils/schema_converter.py:618

    ``examples`` hold instance data, so a ``$ref``-shaped value stored there is
    a payload rather than a reference and must not block tool wrapping.
    """
    if checked_references is None:
        checked_references = set()
    if isinstance(schema, list):
        for item in schema:
            _check_dynamic_references(item, root_schema, checked_references)
        return
    if not isinstance(schema, dict):
        return

    reference = schema.get("$ref")
    if reference is not None:
        if not isinstance(reference, str):
            raise ValueError("Dynamic-key schema `$ref` must be a string")
        resolved = _resolve_local_json_pointer(reference, root_schema)
        if not isinstance(resolved, (dict, bool)):
            raise ValueError(
                f"Dynamic-key schema reference {reference!r} does not target a schema"
            )
        if reference not in checked_references:
            checked_references.add(reference)
            _check_dynamic_references(resolved, root_schema, checked_references)

    for keyword, value in schema.items():
        if keyword in _SCHEMA_VALUED_KEYWORDS or keyword in _SCHEMA_LIST_KEYWORDS:
            _check_dynamic_references(value, root_schema, checked_references)
        elif keyword in _SCHEMA_MAP_KEYWORDS:
            if isinstance(value, dict):
                for entry in value.values():
                    _check_dynamic_references(entry, root_schema, checked_references)
        elif keyword == "items":
            # A schema, or a list of schemas for tuple validation.
            _check_dynamic_references(value, root_schema, checked_references)
        elif keyword == "dependencies":
            # Each entry is either a schema or a list of required property names.

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Retarget the $ref to a node that is an actual schema object (or boolean)
  2. Move non-schema constants out of definitions, or wrap the referenced value in {"enum": [...]} and point at that
  3. Re-validate the document structure before conversion

Example fix

# before
{"$defs": {"role": "admin"}, "$ref": "#/$defs/role"}
# after
{"$defs": {"role": {"enum": ["admin"]}}, "$ref": "#/$defs/role"}
Defensive patterns

Strategy: validation

Validate before calling

def ref_targets_schema(ref, root):
    cur = root
    for tok in ref[2:].split("/"):
        tok = tok.replace("~1", "/").replace("~0", "~")
        cur = cur.get(tok) if isinstance(cur, dict) else (cur[int(tok)] if isinstance(cur, list) and tok.isdigit() and int(tok) < len(cur) else None)
        if cur is None: return False
    return isinstance(cur, (dict, bool))

Try / catch

try:
    build_model(schema)
except ValueError as e:
    if "does not target a schema" in str(e):
        schema = retarget_or_wrap_ref_target(schema)

Prevention

When it happens

Trigger: "$ref": "#/definitions/label" where definitions.label is the string "user" (an enum value leaked into definitions); pointers aimed at examples, descriptions, or other metadata nodes instead of schema nodes.

Common situations: Schemas that also store constants/enums under definitions and a ref accidentally points there; pointer off-by-one errors landing on a sibling key; LLM- or template-authored schemas confusing values with schemas.

Related errors


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