'JSON Schema: Error due to validion against more than one schema from 'oneOf'
I have a JSON schema that is checked by series of if statements in oneOf. However, it fails due to the fact that one of the property appears in 3 if statements(see errors below). How do I force checking of properties as groups ?
Used https://www.jsonschemavalidator.net/ to validate schema.
Schema:
{
"$id": "https://json-schema.hyperjump.io/schema2",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"Occupancy": {
"type": "string",
"enum": [
"Owner Occupied",
"Tenant"
]
},
"DwellingUse": {
"type": "string",
"enum": [
"Dwelling",
"Apartment",
"Other Buildings",
"Townhouses",
"Condominiums",
"Duplex",
"Triplex"
]
},
"Form": {
"type": "string",
"enum": [
"HO-2 Broad Form",
"HO-3 Special Form",
"HO-5 Comprehensive Form"
]
},
"DwellingAmount": {
"type": "integer",
"maximum": 999999999
},
"OtherStructuresAmount": {
"type": "integer",
"maximum": 999999999,
"minimum": 0
}
},
"oneOf": [
{
"if": {
"properties": {
"Occupancy": {
"const": "Tenant"
}
}
},
"then": {
"properties": {
"Form": {
"enum": [
"HO-BT Broad Form",
"HO-CT All-Risk Form",
"HO-4 Tenant"
]
},
"DwellingAmount": {
"const": 0
},
"OtherStructuresAmount": {
"const": 0
}
}
}
},
{
"if": { //Both properties must be checked and match
"properties": {
"Occupancy": {
"const": "Owner Occupied"
},
"DwellingUse": {
"const": "Condominiums"
}
}
},
"then": {
"properties": {
"Form": {
"enum": [
"HO-B Con Broad Form",
"HO-C Con All-Risk Form",
"HO-6 Condominium"
]
},
"OtherStructuresAmount": {
"const": 0
}
},
"required": [
"DwellingAmount"
]
}
},
{
"if": { //Both properties must be checked and match
"properties": {
"Occupancy": {
"const": "Owner Occupied"
},
"DwellingUse": {
"const": "Apartment"
}
}
},
"then": {
"properties": {
"Form": {
"enum": [
"HO-4 Contents Broad Form"
]
},
"DwellingAmount": {
"const": 0
},
"OtherStructuresAmount": {
"const": 0
}
}
}
},
{
"if": {
"properties": {
"Occupancy": {
"const": "Owner Occupied"
}
}
},
"then": {
"properties": {
"Form": {
"enum": [
"HO-A Limited Form",
"HO-B Broad Form",
"HO-C All-Risk Form",
"HO-3 Broad Form",
"HO-8 Modified Form"
]
}
},
"required": [
"DwellingAmount",
"OtherStructuresAmount"
]
}
}
],
"additionalProperties": false
}
Input for validation:
{
"Occupancy": "Owner Occupied",
"DwellingUse": "Condominiums",
"Form": "HO-B Con Broad Form",
"DwellingAmount": 5,
"OtherStructuresAmount": 0
}
Error:
Found 4 error(s)
Message:
Value "HO-B Con Broad Form" is not defined in enum.
Schema path:
https://json-schema.hyperjump.io/schema2#/properties/Form/enum
Message:
JSON is valid against more than one schema from 'oneOf'. Valid schema indexes: 0, 1, 2.
Schema path:
https://json-schema.hyperjump.io/schema2#/oneOf
Message:
JSON does not match schema from 'then'.
Schema path:
https://json-schema.hyperjump.io/schema2#/oneOf/3/then/then
Message:
Value "HO-B Con Broad Form" is not defined in enum.
Schema path:
https://json-schema.hyperjump.io/schema2#/oneOf/3/then/properties/Form/enum
Solution 1:[1]
It's hard to tell what you're looking for. Are you expecting that the data you provided here should pass validation? It won't, because your "Form" value isn't in the enum (as per the first error message).
Also be aware that an if clause will evaluate as true if the given property doesn't exist in your data at all -- so to ensure that it does exist, you need to add "required": [<property name>].
Also, if the if clause is false, then the else clause will evaluate. And if there isn't one, then the result is true -- so if you have multiple conditions where the if is false, you will have multiple else clauses running, and if they are all true, then you will violate your oneOf restriction.
There are multiple ways of solving this: either use else: false with every condtional, or change the oneOf to an allOf.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ether |
