json-schema-spec
json-schema-spec copied to clipboard
`$dynamicRef` behavior when there is no URI with the same fragment in the dynamic scope
https://json-schema.org/draft/2020-12/json-schema-core.html#dynamic-ref
If the initially resolved starting point URI includes a fragment that was created by the "$dynamicAnchor" keyword, the initial URI MUST be replaced by the URI (including the fragment) for the outermost schema resource in the dynamic scope that defines an identically named fragment with "$dynamicAnchor".
Otherwise, its behavior is identical to "$ref", and no runtime resolution is needed.
{
"$dynamicRef": "#foo",
"$defs": {
"a": {
"$dynamicAnchor": "foo"
}
}
}
In this example, the initially resolved starting point URI of $dynamicRef includes a fragment that was created by the $dynamicAnchor, but when we try to find "the outermost schema resource in the dynamic scope that defines an identically named fragment with $dynamicAnchor", we are not able to find anything.
What should an implementation do in this situation? Should behavior be identical to $ref, or maybe it's undefined behavior, and implementation could raise an error?
The first step is resolving the $dynamicRef just like $ref -- #foo is resolved against the base uri (which in this case is '', nothing), and we find the 'foo' anchor at /$defs/a. Then we examine our dynamic scope to see if we "passed by" any other scopes containing $dynamicAnchors named foo. We didn't (our list of dynamic scopes is just '', so there are no more scopes to examine for anchors named foo), so our final landing spot is /$defs/a. That's the "otherwise, its behaviour is identical to $ref" bit.
In this case, the wording looks a little confusing.
If the initially resolved starting point URI includes a fragment that was created by the "$dynamicAnchor" keyword, the initial URI MUST be replaced ...
This part looks like we assume that there MUST be a corresponding schema in the dynamic scope.
No, because there is an "if... otherwise..." ?
If you can think of a way to make this clear, please let us know! It's one of the most confusing parts of the spec for sure.
I spent some time figuring out how to make it clear and realized that it's tough to do without making it wordy.
My suggestion is to replace the "Otherwise ..." part with something like:
In the following cases, the behavior of this keyword is identical to "$ref", and no runtime resolution is needed:
- The initially resolved starting point URI does not include a fragment that was created by the "$dynamicAnchor" keyword.
- The dynamic scope does not contain a schema resource that defines an identically named fragment with "$dynamicAnchor".
@karenetheridge, what do you think about this option? Maybe it looks clearer only for me :)
@yakimun see also #1140
The language in question was removed in #1139.