Skip to content

$dynamicRef doesn't find $dynamicAnchor overrides in root schemas without $id #1497

@aqeelat

Description

@aqeelat

$dynamicRef doesn't find $dynamicAnchor overrides in root schemas without $id

When a root schema has no $id and uses $ref to pull in a template containing $dynamicRef, the $dynamicRef ignores any $dynamicAnchor overrides defined in the root schema's $defs. It falls back to the template's own $dynamicAnchor instead.

Minimal reproducer

from jsonschema import Draft202012Validator
from referencing import Registry, Resource
from referencing.jsonschema import DRAFT202012

template = {
    "$id": "https://example.com/PaginatedTemplate",
    "$defs": {"itemType": {"$dynamicAnchor": "itemType", "not": {}}},
    "type": "object",
    "required": ["items"],
    "properties": {"items": {"type": "array", "items": {"$dynamicRef": "#itemType"}}}
}

schema = {
    "$defs": {"itemType": {"$dynamicAnchor": "itemType", "type": "string"}},
    "$ref": "https://example.com/PaginatedTemplate"
}

registry = Registry().with_resource(
    "https://example.com/PaginatedTemplate",
    Resource.from_contents(template, default_specification=DRAFT202012)
)

# Should pass — "hello" matches the override (type: string)
# Actually fails — $dynamicRef resolves to the template's not: {} instead
v = Draft202012Validator(schema, registry=registry)
assert not list(v.iter_errors({"items": ["hello"]}))  # fails

Adding $id to the root schema makes it work:

schema["$id"] = "https://example.com/Bound"
# ... then register and validate — passes

Workaround

Add a synthetic $id to the root schema before creating the validator.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions