ComposioHQ/composio · error · ValueError
Unresolvable dynamic-key schema reference: {reference!r}
Error message
Unresolvable dynamic-key schema reference: {reference!r} What it means
The $ref is a well-formed local JSON Pointer ("#/...") but the pointer path does not exist in the root schema: a token doesn't match a key, or a list index is invalid/out of range. _resolve_local_json_pointer walks the tokens (applying ~0/~1 unescaping) and raises this ValueError when traversal dead-ends.
Source
Thrown at python/composio/utils/schema_converter.py:360
return root_schema
if not reference.startswith("#/"):
raise ValueError(
f"Dynamic-key schema reference {reference!r} must be a local JSON Pointer"
)
current: t.Any = root_schema
for raw_token in unquote(reference[2:]).split("/"):
token = raw_token.replace("~1", "/").replace("~0", "~")
if isinstance(current, dict) and token in current:
current = current[token]
continue
if isinstance(current, list):
try:
current = current[int(token)]
continue
except (ValueError, IndexError):
pass
raise ValueError(f"Unresolvable dynamic-key schema reference: {reference!r}")
return current
def _resolve_default_metadata_schema(
schema: t.Any,
root_schema: t.Dict[str, t.Any],
visited_refs: t.Optional[t.Set[str]] = None,
) -> t.Any:
"""Resolve a schema node without traversing instance-valued annotations."""
if not isinstance(schema, dict):
return schema
reference = schema.get("$ref")
if not isinstance(reference, str) or not reference.startswith("#/"):
return schema
if visited_refs is None:
visited_refs = set()
if reference in visited_refs:
return {key: value for key, value in schema.items() if key != "$ref"}View on GitHub (pinned to 64b1b85502)
Solutions
- Verify the exact token path against the root schema (check spelling/case of every key under definitions/$defs)
- Re-fetch or regenerate the schema pair so refs and definitions come from the same source
- If the target was renamed, update the $ref to the new location
Example fix
# before
{"$ref": "#/definitions/Usr"}
# after
{"$ref": "#/definitions/User"} Defensive patterns
Strategy: validation
Validate before calling
from jsonschema import RefResolver # or manual pointer walk
def pointer_resolves(ref, root):
if ref == "#": return True
if not ref.startswith("#/"): return False
cur = root
for tok in ref[2:].split("/"):
tok = tok.replace("~1", "/").replace("~0", "~")
if isinstance(cur, dict) and tok in cur: cur = cur[tok]
elif isinstance(cur, list) and tok.isdigit() and int(tok) < len(cur): cur = cur[int(tok)]
else: return False
return True Try / catch
try:
build_model(schema)
except ValueError as e:
if "Unresolvable" in str(e):
raise ToolSchemaError(f"stale ref in {tool.name}: {e}") from e Prevention
- Keep definitions and refs in the same document/source version
- Regenerate schema pairs together rather than mixing old refs with new definitions
- Add a pointer-resolution pre-check in schema tests
When it happens
Trigger: "$ref": "#/definitions/MissingName" when definitions lacks that key; pointing into an array element that doesn't exist ("#/items/5"); typos in the pointer path; refs valid against a different root document than the one passed in.
Common situations: Renamed or removed definitions in a regenerated schema while stale refs remain; schemas copy-pasted between documents where the target was left behind; case mismatches in definition names; version skew between cached and refreshed tool schemas.
Related errors
- Cannot resolve $ref {pointer}
- Dynamic-key schema reference {reference!r} must be a local J
- Dynamic-key schema `$ref` must be a string
- Dynamic-key schema reference {reference!r} does not target a
- Unsupported $ref pointer: ${pointer}
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/ecdf668a49a1ae12.
Report an issue: GitHub.