Alex
Alex

Reputation: 3

JSON Schema not working as expected with if/then/else

I have the following schema:

{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "default": "United States of America",
      "enum": ["United States of America", "Canada", "Netherlands"]
    }
  },
  "allOf": [
    {
      "if": {
        "properties": { "country": { "const": "United States of America" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
      }
    },
    {
      "if": {
        "properties": { "country": { "const": "Canada" } },
        "required": ["country"]
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
      }
    },
    {
      "if": {
        "properties": { "country": { "const": "Netherlands" } },
        "required": ["country"]
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
      }
    }
  ]
}

It is a copy from here https://json-schema.org/understanding-json-schema/reference/conditionals.html

When I change allOf keyword to anyOf it gives me unexpected results. I am using Ajv for validation.

The validation passes even with this data: { country: "Canada", postal_code: "some invalid code" }

But when I leave only one if/then statement (for Canada) it fails as expected. In the case when I change keyword to oneOf it fails because there is more than one passing schema.

Why is it happening?

Upvotes: 0

Views: 809

Answers (1)

Ether
Ether

Reputation: 53966

Your conditionals don't have any "else" clauses -- so if the if part is false, the else will default to true which will cause that branch of the allOf to be true. You probably want to add an "else": false to each one of those.

(Also, I noticed your regexes aren't anchored - so e.g. "abc01234xyz" will match your US postal_code pattern.)

Upvotes: 2

Related Questions