oneOf Validation Issue

1,104 views
Skip to first unread message

Tim McDowell

unread,
Sep 23, 2019, 11:39:58 AM9/23/19
to JSON Schema

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"}.

Message has been deleted

Ben Hutton (@Relequestual)

unread,
Sep 23, 2019, 11:54:29 AM9/23/19
to JSON Schema

Hey Tim,

 

This is a pretty common stumbling block here, so don’t worry.

 

You’re schema looks OK, but it’s not doing what you want.

 

You’ve assumed that the validation path should go down `oneOf[1]` and find it valid, and go down `one of[0]` and find it invalid, and so pass the overall `oneOf`.

 

Test your assumption.

What happens if you use the first subschema on its own?

Passes validation, right? As a result, `oneOf` is false, as it’s valid according to more than one subschema.

 

This is because it only expresses constraints for a property `test1`. Omission of a property key does not mean such is invalid.

`properties` only applies subschemas when the keys match, but does not place any constraint on the allowed keys of the object.

 

If you want to prevent additional properties in a schema, you need to use the `additionalProperties` keyword, with a value of false.

 

I’m addressing this common pitfall in my upcoming talk at ASC2019.

https://asc2019.sched.com/event/T6ud/json-schema-core-concepts-common-pitfalls-and-debugging-ben-hutton-json-schema

 

(20% off registration code: ASCSOCIAL19 if you can make it!)

 

Out of interest, what’s the reason for using `oneOf` here? A simplified example for demo purposes?

 

Feel free to use your much more complex schema and share using https://jsonschema.dev

 

 

Cheers

Ben

Tim McDowell

unread,
Sep 24, 2019, 9:45:21 AM9/24/19
to JSON Schema

Ben -

Thanks for the explanation - it makes perfect sense now.  Making the properties required has the same effect of forcing the check to be made. 

It was a very simple example to understand how oneOf works before using it on a more complex schema.  I now have that schema working as well.

Tim

---
Timothy P. McDowell Executive Vice President Thermal Energy System Specialists, LLC 3 N Pinckney St, Suite 202 Madison, WI 53703 office: 608-274-2577 cell: 608-225-5250

On 2019-09-23 10:48, Ben Hutton wrote:

Hey Tim,

 

This is a pretty common stumbling block here, so don’t worry.

 

You’re schema looks OK, but it’s not doing what you want.

 

You’ve assumed that the validation path should go down `oneOf[1]` and find it valid, and go down `one of[0]` and find it invalid, and so pass the overall `oneOf`.

 

Test your assumption.

What happens if you use the first subschema on its own?

Passes validation, right? As a result, `oneOf` is false, as it’s valid according to more than one subschema.

 

This is because it only expresses constraints for a property `test1`. Omission of a property key does not mean such is invalid.

`properties` only applies subschemas when the keys match, but does not place any constraint on the allowed keys of the object.

 

If you want to prevent additional properties in a schema, you need to use the `additionalProperties` keyword, with a value of false.

 

I’m addressing this common pitfall in my upcoming talk at ASC2019.

https://asc2019.sched.com/event/T6ud/json-schema-core-concepts-common-pitfalls-and-debugging-ben-hutton-json-schema

 

(20% off registration code: ASCSOCIAL19 if you can make it!)

 

Out of interest, what’s the reason for using `oneOf` here? A simplified example for demo purposes?

 

Feel free to use your much more complex schema and share using https://jsonschema.dev

 

 

Cheers

Ben

 

-- The Wellcome Sanger Institute is operated by Genome Research Limited, a charity registered in England with number 1021457 and a company registered in England with number 2742969, whose registered office is 215 Euston Road, London, NW1 2BE.
Reply all
Reply to author
Forward
0 new messages