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
- Retarget the $ref to a node that is an actual schema object (or boolean)
- Move non-schema constants out of definitions, or wrap the referenced value in {"enum": [...]} and point at that
- 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
- Keep constants/enums out of definitions, or wrap them in {"enum": [...]}
- Unit-test that every $ref resolves to a dict or boolean
- Generate refs programmatically from the target's location
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
- Dynamic-key schema `$ref` must be a string
- Cannot resolve $ref {pointer}
- Dynamic-key schema reference {reference!r} must be a local J
- Unresolvable dynamic-key schema reference: {reference!r}
- Unsupported $ref pointer: ${pointer}
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/52c0abcc664c3425.
Report an issue: GitHub.