jsonschema
jsonschema copied to clipboard
Unresolvable JSON pointer: 'meta' when embedding 2020-12 metaschema
jsonschema is unable to resolve the "#meta"
references in the 2020-12 meta-schema when that meta-schema is embedded in a schema that also uses the 2020-12 meta-schema:
jsonschema.exceptions.RefResolutionError: Unresolvable JSON pointer: 'meta'
Reproducing
- Python 3.8.10
- jsonschema 4.2.1
schema.json
:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schema/foo",
"type": "object",
"properties": {
"foo": {
"type": "string"
},
"subschema": {
"$ref": "https://json-schema.org/draft/2020-12/schema"
}
}
}
data.json
:
{
"foo": "bar",
"subschema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schema/bar",
"type": "object",
"properties": {
"bar": {
"type": "string"
}
}
}
}
main.py
:
import json
import os
import traceback
import jsonschema
SCHEMA_2019 = "https://json-schema.org/draft/2019-09/schema"
SCHEMA_2020 = "https://json-schema.org/draft/2020-12/schema"
def read(name):
base_path = os.path.join(os.path.dirname(__file__))
with open(os.path.join(base_path, name), 'r') as f:
return json.load(f)
def test(name, data, schema):
try:
jsonschema.validate(data, schema)
except jsonschema.RefResolutionError as e:
print('FAIL', name)
print(traceback.format_exc())
else:
print('SUCCESS', name)
def main():
schema = read('schema.json')
data = read('data.json')
test('All 2020', data, schema)
schema["$schema"] = SCHEMA_2019
test('Root 2019', data, schema)
schema["$schema"] = SCHEMA_2020
schema["properties"]["subschema"]["$ref"] = SCHEMA_2019
test('Subschema 2019', data, schema)
schema["$schema"] = SCHEMA_2020
test('Both 2019', data, schema)
if __name__ == '__main__':
main()
Expected output
SUCCESS All 2020
SUCCESS Root 2019
SUCCESS Subschema 2019
SUCCESS Both 2019
Actual output
FAIL All 2020
Traceback (most recent call last):
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 844, in resolve_fragment
document = document[part]
KeyError: 'meta'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 17, in test
jsonschema.validate(data, schema)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 965, in validate
error = exceptions.best_match(validator.iter_errors(instance))
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/exceptions.py", line 354, in best_match
best = next(errors, None)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 224, in iter_errors
for error in errors:
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/_validators.py", line 332, in properties
yield from validator.descend(
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 240, in descend
for error in self.evolve(schema=schema).iter_errors(instance):
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 224, in iter_errors
for error in errors:
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/_validators.py", line 298, in ref
yield from validator.descend(instance, resolved)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 240, in descend
for error in self.evolve(schema=schema).iter_errors(instance):
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 224, in iter_errors
for error in errors:
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/_validators.py", line 362, in allOf
yield from validator.descend(instance, subschema, schema_path=index)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 240, in descend
for error in self.evolve(schema=schema).iter_errors(instance):
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 224, in iter_errors
for error in errors:
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/_validators.py", line 298, in ref
yield from validator.descend(instance, resolved)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 240, in descend
for error in self.evolve(schema=schema).iter_errors(instance):
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 224, in iter_errors
for error in errors:
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/_validators.py", line 332, in properties
yield from validator.descend(
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 240, in descend
for error in self.evolve(schema=schema).iter_errors(instance):
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 224, in iter_errors
for error in errors:
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/_validators.py", line 46, in additionalProperties
yield from validator.descend(instance[extra], aP, path=extra)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 240, in descend
for error in self.evolve(schema=schema).iter_errors(instance):
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 224, in iter_errors
for error in errors:
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/_validators.py", line 308, in dynamicRef
with validator.resolver.resolving(lookup_url) as subschema:
File "/usr/lib/python3.8/contextlib.py", line 113, in __enter__
return next(self.gen)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 752, in resolving
url, resolved = self.resolve(ref)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 783, in resolve
subschema = self.resolve_fragment(subschema, fragment)
File "/home/ubuntu/.local/share/virtualenvs/linker-prototype-uUKgQqax/lib/python3.8/site-packages/jsonschema/validators.py", line 846, in resolve_fragment
raise exceptions.RefResolutionError(
jsonschema.exceptions.RefResolutionError: Unresolvable JSON pointer: 'meta'
SUCCESS Root 2019
SUCCESS Subschema 2019
SUCCESS Both 2019
Additional notes
- Changing the meta-schema set in
data.json
'ssubschema.$schema
does not have an effect on outcome. - Also happens on jsonschema
4.0.0
A minimal example:
import jsonschema
schema = {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schema/foo",
"properties": {
"subschema": {"$ref": "https://json-schema.org/draft/2020-12/schema"}
}
}
data = {
"subschema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"bar": {"type": "string"}
}
}
}
jsonschema.validate(data, schema)
Could I please get another look at this ticket, @Julian? I added a minimal reproduction at https://github.com/Julian/jsonschema/issues/884#issuecomment-977882583.
Thanks -- the minimized example certainly looks good -- the next steps would be a change was just merged fixing dynamicRef support (in that all tests of it in the suite currently pass now). Can you test your example with master? If it passes, great, that means it should be fixed with the next release.
If it doesn't, now we need to figure out where the bug is, add a test for it to the upstream suite, and put in a fix.
I doubt I'll have time to look myself in the next 2 weeks at very least, I've got a ton that's about to hit with the academic semester starting, but I can review a PR if needed.
EDIT: Further minimized:
import jsonschema
jsonschema.validate(
instance={
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {"bar": {}}
},
schema={
"$id": "https://example.com/schema/foo",
"$ref": "https://json-schema.org/draft/2020-12/schema"
},
)
I'm still getting the same error when running on latest main (6787b213d8b5bdad5af29b7c96aeef7ec715aa02
).
Hello there!
This, along with many many other $ref
-related issues, is now finally being handled in #1049 with the introduction of a new referencing library which is fully compliant and has APIs which I hope are a lot easier to understand and customize.
The next release of jsonschema
(v4.18.0) will contain a merged version of that PR, and should be released shortly in beta, and followed quickly by a regular release, assuming no critical issues are reported.
It looks from my testing like indeed this specific example works there! If you still care to, I'd love it if you tried out the beta once it is released, or certainly it'd be hugely helpful to immediately install the branch containing this work (https://github.com/python-jsonschema/jsonschema/tree/referencing) and confirm. You can in the interim find documentation for the change in a preview page here.
I'm going to close this given it indeed seems like it is addressed by #1049, but feel free to follow up with any comments. Sorry for the delay in getting to these, but hopefully this new release will bring lots of benefit!