domderen
domderen

Reputation: 643

JSON Schema oneOf validation

I'm trying to create a JSON Schema that will allow a property to be either a number or an object of a specific format.

My data looks like this:

{
  "num": 200
}

and my Schema looks like this:

{
  "properties": {
    "num": {
      "type": [
        "number",
        "object"
      ],
      "oneOf": [
        {
          "type": "number"
        },
        {
          "$ref": "#/definitions/Variable"
        }
      ]
    }
  },
  "required": [
    "num"
  ],
  "additionalProperties": false,
  "definitions": {
    "Variable": {
      "title": "Variable",
      "properties": {
        "$variable$": {
          "type": "boolean",
          "example": true
        },
        "name": {
          "type": "string"
        },
        "defaultValue": {
          "type": [
            "string",
            "object",
            "number"
          ]
        }
      },
      "required": [
        "$variable$",
        "name"
      ],
      "additionalProperties": false
    }
  }
}

When I run it via a validator here: https://www.jsonschemavalidator.net/

I get this error:

Message: JSON is valid against more than one schema from 'oneOf'. Valid schema indexes: 0, 1.
Schema path: #/properties/num/oneOf

I'm assuming I'm missing something obvious about how oneOf works, but I can't figure out what it might me. Would appreciate any help here, thanks!

Upvotes: 1

Views: 10057

Answers (2)

Jason Desrosiers
Jason Desrosiers

Reputation: 24399

The error you are getting is telling you that both of you oneOf schemas are validating as true. It might be surprising that the value 4 is valid against the following schema.

{
  "properties": {
    "foo": { "type": "string": }
  },
  "required": ["foo"]
}

It turns out that the properties keyword and the required keyword don't apply when the value is not an object. So, the above schema is effectively the empty schema ({}) when validating against a number (or anything that is not an object). Because the empty schema means there are no constraints, everything is valid.

To fix your problem just add "type": "object" to your /definitions/Variable schema.

Upvotes: 4

KS12
KS12

Reputation: 32

For your case you don't need oneOf at all, you can simply use "type": ["number",{"$ref":"#/definitions/Variable"}] instead of "type": ["number","object"]

{
  "properties": {
    "num": {
      "type": [
        "number",{"$ref":"#/definitions/Variable"}
      ]
    }
  },
  "required": [
    "num"
  ],
  "additionalProperties": false,
  "definitions": {
    "Variable": {
      "title": "Variable",
      "properties": {
        "$variable$": {
          "type": "boolean",
          "example": true
        },
        "name": {
          "type": "string"
        },
        "defaultValue": {
          "type": [
            "string",
            "object",
            "number"
          ]
        }
      },
      "required": [
        "$variable$",
        "name"
      ],
      "additionalProperties": false
    }
  }
}

Upvotes: -1

Related Questions