$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.
$dynamicRef doesn't find $dynamicAnchor overrides in root schemas without $id
When a root schema has no
$idand uses$refto pull in a template containing$dynamicRef, the$dynamicRefignores any$dynamicAnchoroverrides defined in the root schema's$defs. It falls back to the template's own$dynamicAnchorinstead.Minimal reproducer
Adding
$idto the root schema makes it work:Workaround
Add a synthetic
$idto the root schema before creating the validator.