I have a schema that heavily utilises $dynamicRef to inject parts of schema from other files.
Namely, here is the base schema:
base.json:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "base.json",
"type": "object",
"additionalProperties": false,
"properties": {
"orderNumber": {
"type": "integer",
"minimum": 0
},
"downstreamNumber": {
"$dynamicRef": "#specialDownstreamNumber"
},
"schemaName": {
"$dynamicRef": "#concreteName"
},
"schemaVersion": {
"$dynamicRef": "#concreteVersion"
},
"timestamp": {
"type": "integer"
},
"data": {
"$dynamicRef": "#concreteData"
}
},
"required": [
"data",
"orderNumber",
"schemaName",
"schemaVersion",
"downstreamNumber",
"timestamp"
],
"$defs": {
"name": {
"const": "base",
"$dynamicAnchor": "concreteName"
},
"version": {
"const": "0.0.0",
"$dynamicAnchor": "concreteVersion"
},
"data": {
"not": true,
"$dynamicAnchor": "concreteData"
},
"downstreamNumber": {
"type": "integer",
"minimum": 1,
"$dynamicAnchor": "specialDownstreamNumber"
}
}
}
And here is the specific JSON that fills in the data for the base:
camera.json:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "camera.json",
"$ref": "base.json",
"$defs": {
"name": {
"const": "camera.info",
"$dynamicAnchor": "concreteName"
},
"version": {
"const": "1.0.0",
"$dynamicAnchor": "concreteVersion"
},
"data": {
"$dynamicAnchor": "concreteData",
"type": "object",
"additionalProperties": false,
"properties": {
"cameraFacing": {
"enum": [
"Front",
"Back"
]
},
"cameraFrameSize": {
"$ref": "#/$defs/size"
},
"roi": {
"$ref": "#/$defs/size"
},
"viewPortAspectRatio": {
"type": "number"
}
},
"required": [
"cameraFacing",
"cameraFrameSize",
"roi",
"viewPortAspectRatio"
]
},
"downstreamNumber": {
"type": "integer",
"minimum": 0,
"$dynamicAnchor": "specialDownstreamNumber"
},
"size": {
"type": "object",
"additionalProperties": false,
"properties": {
"width": {
"type": "integer"
},
"height": {
"type": "integer"
}
},
"required": [
"width",
"height"
]
}
}
}
Here is the JSON that I'm trying to validate:
{
"orderNumber": 4,
"downstreamNumber": 1,
"schemaVersion": "1.0.0",
"schemaName": "camera.info",
"timestamp": 1756525700,
"data": {
"cameraFacing": "Back",
"cameraFrameSize": {
"width": 3841,
"height": 2161
},
"roi": {
"width": 3840,
"height": 1858
},
"viewPortAspectRatio": 2.066
}
}
Here is how I'm doing the validation:
import json
from pathlib import Path
from jsonschema.validators import Draft202012Validator
from referencing import Registry, Resource
ROOT = Path(__file__).absolute().parent
SCHEMAS = ROOT / Path("schema")
def validate_file(validator: Draft202012Validator, file: Path):
with open(file, "rt", encoding="utf-8") as f:
instance = json.load(f)
instance = json.loads(file.read_text())
print(f"Validating {file}...")
validator.validate(instance)
def retrieve_from_filesystem(uri: str):
path = SCHEMAS / Path(uri)
contents = json.loads(path.read_text())
return Resource.from_contents(contents)
def main():
registry = Registry(retrieve=retrieve_from_filesystem)
schema_file = SCHEMAS / Path("camera.json")
with open(schema_file, "rt", encoding="utf-8") as f:
schema = json.load(f)
validator = Draft202012Validator(
schema,
registry=registry
)
tests_path = ROOT / Path("payload")
for file in tests_path.iterdir():
validate_file(validator, file)
if __name__ == "__main__":
main()
The validation fails with exception:
jsonschema.exceptions._WrappedReferencingError: PointerToNowhere: '/$defs/size' does not exist within {'$schema': 'https://json-schema.org/draft/2020-12/schema', '$id': 'base.json', 'type': 'object', 'additionalProperties': False, 'properties': {'orderNumber': {'type': 'integer', 'minimum': 0}, 'downstreamNumber': {'$dynamicRef': '#specialDownstreamNumber'}, 'schemaName': {'$dynamicRef': '#concreteName'}, 'schemaVersion': {'$dynamicRef': '#concreteVersion'}, 'timestamp': {'type': 'integer'}, 'data': {'$dynamicRef': '#concreteData'}}, 'required': ['data', 'orderNumber', 'schemaName', 'schemaVersion', 'downstreamNumber', 'timestamp'], '$defs': {'name': {'const': 'base', '$dynamicAnchor': 'concreteName'}, 'version': {'const': '0.0.0', '$dynamicAnchor': 'concreteVersion'}, 'data': {'not': True, '$dynamicAnchor': 'concreteData'}, 'downstreamNumber': {'type': 'integer', 'minimum': 1, '$dynamicAnchor': 'specialDownstreamNumber'}}}
Which is incorrect, as camera.json does contain /$defs/size. I've tried validating the payload with a different validator and it validates the payload successfully.
I don't see anything wrong with my schema definitions and boon has no problem validating the payload.
Is this a bug in jsonschema library or did I do something wrong and boon fails to detect it?
I have a schema that heavily utilises
$dynamicRefto inject parts of schema from other files.Namely, here is the base schema:
base.json:{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "base.json", "type": "object", "additionalProperties": false, "properties": { "orderNumber": { "type": "integer", "minimum": 0 }, "downstreamNumber": { "$dynamicRef": "#specialDownstreamNumber" }, "schemaName": { "$dynamicRef": "#concreteName" }, "schemaVersion": { "$dynamicRef": "#concreteVersion" }, "timestamp": { "type": "integer" }, "data": { "$dynamicRef": "#concreteData" } }, "required": [ "data", "orderNumber", "schemaName", "schemaVersion", "downstreamNumber", "timestamp" ], "$defs": { "name": { "const": "base", "$dynamicAnchor": "concreteName" }, "version": { "const": "0.0.0", "$dynamicAnchor": "concreteVersion" }, "data": { "not": true, "$dynamicAnchor": "concreteData" }, "downstreamNumber": { "type": "integer", "minimum": 1, "$dynamicAnchor": "specialDownstreamNumber" } } }And here is the specific JSON that fills in the data for the base:
camera.json:{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "camera.json", "$ref": "base.json", "$defs": { "name": { "const": "camera.info", "$dynamicAnchor": "concreteName" }, "version": { "const": "1.0.0", "$dynamicAnchor": "concreteVersion" }, "data": { "$dynamicAnchor": "concreteData", "type": "object", "additionalProperties": false, "properties": { "cameraFacing": { "enum": [ "Front", "Back" ] }, "cameraFrameSize": { "$ref": "#/$defs/size" }, "roi": { "$ref": "#/$defs/size" }, "viewPortAspectRatio": { "type": "number" } }, "required": [ "cameraFacing", "cameraFrameSize", "roi", "viewPortAspectRatio" ] }, "downstreamNumber": { "type": "integer", "minimum": 0, "$dynamicAnchor": "specialDownstreamNumber" }, "size": { "type": "object", "additionalProperties": false, "properties": { "width": { "type": "integer" }, "height": { "type": "integer" } }, "required": [ "width", "height" ] } } }Here is the JSON that I'm trying to validate:
{ "orderNumber": 4, "downstreamNumber": 1, "schemaVersion": "1.0.0", "schemaName": "camera.info", "timestamp": 1756525700, "data": { "cameraFacing": "Back", "cameraFrameSize": { "width": 3841, "height": 2161 }, "roi": { "width": 3840, "height": 1858 }, "viewPortAspectRatio": 2.066 } }Here is how I'm doing the validation:
The validation fails with exception:
Which is incorrect, as
camera.jsondoes contain/$defs/size. I've tried validating the payload with a different validator and it validates the payload successfully.I don't see anything wrong with my schema definitions and boon has no problem validating the payload.
Is this a bug in
jsonschemalibrary or did I do something wrong andboonfails to detect it?