TMcDowell
TMcDowell

Reputation: 21

JSON Schema oneOf Validation Issue

I am working on creating a complex JSON schema and am having issues with validating a "oneOf" construction.

I have created a very simple schema using "oneOf" and a simple JSON file to demonstrate the issue.

JSON Schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",

  "type": "object",
  "oneOf":[
  {"properties": {"test1": {"type": "string"}}},
  {"properties": {"test2": {"type": "number"}}}
  ]
}

JSON File:

{
  "test2":4
}

When I validate the JSON file versus the schema using jsonschema.validate I expect for this to be valid. However I get the error response of:

Traceback (most recent call last):
  File "TestValidate.py", line 11, in <module>
    jsonschema.validate(instance=file, schema=schema, resolver=resolver)
  File "C:\Python36\lib\site-packages\jsonschema\validators.py", line 899, in validate
    raise error
jsonschema.exceptions.ValidationError: {'test2': 4} is valid under each of {'properties': {'test2': {'type': 'number'}}}, {'properties': {'test1': {'type': 'string'}}}

Failed validating 'oneOf' in schema:
    {'$schema': 'http://json-schema.org/draft-07/schema#',
     'oneOf': [{'properties': {'test1': {'type': 'string'}}},
               {'properties': {'test2': {'type': 'number'}}}],
     'type': 'object'}

On instance:
    {'test2': 4}

I don't understand how 'test2': 4 can be valid against "test1": {"type": "string"}.

Upvotes: 2

Views: 3842

Answers (1)

Raphael Medaer
Raphael Medaer

Reputation: 2538

With the following JSON {"test2": 4} both sub-schemas in your oneOf are valid.

Indeed if you try to validate JSON {"test2": 4} with schema {"properties": {"test1": {"type": "string"}}}, it works! Why ? Because field test1 is not in your JSON.

To fix your issue you can either use additionalProperties or required keywords. For instance:

{
  "type": "object",
  "oneOf":[
    {"properties": {"test1": {"type": "string"}}, "required": ["test1"]},
    {"properties": {"test2": {"type": "number"}}, "required": ["test2"]}
  ]
}

or ...

{
  "type": "object",
  "oneOf":[
    {"properties": {"test1": {"type": "string"}}, "additionalProperties": false},
    {"properties": {"test2": {"type": "number"}}, "additionalProperties": false}
  ]
}

Upvotes: 5

Related Questions