unevaluatedProperties : Schema

unevaluatedProperties

Schema

Validates object properties that did not successfully validate against other standard object applicators.

Value This keyword must be set to a valid JSON Schema
Kind Applicator Annotation
Applies To Object
Dialect 2020-12
Changed In None
Introduced In 2019-09
Vocabulary Unevaluated
Specification https://json-schema.org/draft/2020-12/json-schema-core.html#section-11.3
Metaschema https://json-schema.org/draft/2020-12/meta/unevaluated
Official Tests draft2020-12/unevaluatedProperties.json
Default {}
Annotation Array The set of instance property names validated by this keyword's subschema
Affected By
Affects None
Also See

Validation with unevaluatedProperties applies only to the child values of instance names that do not appear in the properties, patternProperties, additionalProperties, or unevaluatedProperties annotation results that apply to the instance location being validated. For all such properties, validation succeeds if the child instance validates against the unevaluatedProperties schema.

Evaluation

It’s crucial to understand what evaluation means in this context.

unevaluatedProperties considers annotations from properties, patternProperties, and additionalProperties, both as adjacent keywords and in subschemas of adjacent keywords. Additionally, it is also affected by other unevaluatedProperties in nested schemas (if present).

  • The keywords properties, patternProperties, additionalProperties, and unevaluatedProperties produce annotations for the properties they successfully validate against.
  • If any of these keywords generate an annotation for a particular property at the same instance location (independently of the schema location), that property is considered as evaluated.
  • By definition, the unevaluatedProperties subschema is always applied after properties, patternProperties, and additionalProperties subschemas.
  • As its name implies, unevaluatedProperties applies to any object property that has not been previously evaluated.

Examples

Schema with 'unevaluatedProperties' set to boolean true Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "unevaluatedProperties": true
}
Valid All object instances pass against the true schema Instance
{ "foo": "bar", "baz": 33 }
Valid 'unevaluatedProperties' does not have any effect on instances other than an object Instance
"John Doe"
Annotations
{ "keyword": "/unevaluatedProperties", "instance": "", "value": [ "foo", "baz" ] }
  • Here, no properties are defined in the above schema. Consequently, all properties in an object instance are considered unevaluated, and the unevaluatedProperties subschema applies to them. Since the subschema here is a boolean true, an instance with unevaluated properties, regardless of their value, is considered valid.
Schema with 'unevaluatedProperties' set to boolean false Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "unevaluatedProperties": false
}
Invalid All object instances fail against the false schema Instance
{ "foo": "bar" }
Valid 'unevaluatedProperties' does not have any effect on instances other than an object Instance
[ "John", 46, false ]
Schema with 'unevaluatedProperties', 'properties', and 'patternProperties', with unevaluatedProperties set to boolean false Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "foo": { "type": "string" }
  },
  "patternProperties": {
    "^b": { "type": "number" }
  },
  "unevaluatedProperties": false
}
Invalid An instance with unevaluated properties is invalid Instance
{ "foo": "foo", "bar": 36, "fooBar": false }
Valid An instance with no unevaluated properties is valid Instance
{ "foo": "foo", "bar": 36 }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "foo" ] }
{ "keyword": "/patternProperties", "instance": "", "value": [ "bar" ] }
  • For the first instance, the annotation result of properties is [ “foo” ], and the annotation result of patternProperties is [ “bar” ]. However, the ‘fooBar’ property remains unevaluated, so the unevaluatedProperties subschema applies to it. This subschema fails (as any instance against a false schema is always invalid), leading to the failure of the entire schema.
  • For the second instance, the annotation result of properties is [ “foo” ], and the annotation result of patternProperties is [ “bar” ]. No properties remain unevaluated; hence, the instance is considered valid.
Schema with 'unevaluatedProperties', 'properties', and 'patternProperties', with unevaluatedProperties set to an object subschema Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "foo": { "type": "string" }
  },
  "patternProperties": {
    "^b": { "type": "number" }
  },
  "unevaluatedProperties": { "type": "boolean" }
}
Valid An instance with no unevaluated properties is valid Instance
{ "foo": "foo", "bar": 36 }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "foo" ] }
{ "keyword": "/patternProperties", "instance": "", "value": [ "bar" ] }
Valid An instance with unevaluated properties that conform to the 'unevaluatedProperties' subschema is valid Instance
{ "foo": "foo", "bar": 36, "fooBar": false }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "foo" ] }
{ "keyword": "/patternProperties", "instance": "", "value": [ "bar" ] }
{ "keyword": "/unevaluatedProperties", "instance": "", "value": [ "fooBar" ] }
Invalid An instance with unevaluated properties that do not conform to the 'unevaluatedProperties' subschema is invalid Instance
{ "foo": "foo", "bar": 36, "fooBar": "string" }
  • For the first instance, there are no unevaluated properties.
  • For the second instance, ‘fooBar’ is unevaluated, and the unevaluatedProperties subschema applies to it. ‘fooBar’ conforms to this subschema, and hence the instance is valid. The annotations produced by applicators are: properties → [ “foo” ], patternProperties → [ “bar” ], and unevaluatedProperties → [ “fooBar” ].
Schema with 'unevaluatedProperties' and 'allOf' keyword Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "foo": { "type": "string" }
  },
  "allOf": [
    {
      "patternProperties": {
        "^b": { "type": "number" }
      }
    }
  ],
  "unevaluatedProperties": { "type": "boolean" }
}
Valid An instance with unevaluated properties that conform to the 'unevaluatedProperties' subschema is valid Instance
{ "foo": "foo", "bar": 36, "fooBar": false }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "foo" ] }
{ "keyword": "/allOf/0/patternProperties", "instance": "", "value": [ "foo" ] }
{ "keyword": "/unevaluatedProperties", "instance": "", "value": [ "fooBar" ] }

Invalid An instance with unevaluated properties that do not conform to the 'unevaluatedProperties' subschema is invalid Instance
{ "foo": "foo", "bar": 36, "fooBar": "string" }
For the above two instances, the annotation result of properties is [ “foo” ], and the annotation result of nested patternProperties is [ “bar” ]. The unevaluatedProperties recognizes the annotations from properties as well as patternProperties (as it can see through adjacent and nested applicators as only the produced annotations matter, not the schema structure) and ensures that ‘fooBar’ remains unevaluated and its subschema applies to ‘fooBar’.

  • The first instance passes as it conforms to the unevaluated subschema.
  • The second instance fails as it does not conform to the unevaluated subschema.
Schema with 'unevaluatedProperties' and 'allOf' keyword Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "foo": { "type": "string" }
  },
  "allOf": [
    {
      "additionalProperties": true
    }
  ],
  "unevaluatedProperties": false
}
Valid An instance with no unevaluated properties is valid Instance
{ "foo": "foo" }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "foo" ] },
{ "keyword": "/allOf/0/additionalProperties", "instance": "", "value": [ "foo" ] }
Valid An instance with no unevaluated properties is valid Instance
{ "foo": "foo", "bar": "bar" }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "foo" ] }
{ "keyword": "/allOf/0/additionalProperties", "instance": "", "value": [ "foo", "bar" ] }
  • In the first case, there are no unevaluated properties.
  • In the second case, the nested { additionalProperties: true } evaluated all the remaining properties. So there’s nothing left unevaluated.
Schema with 'unevaluatedProperties' and '#ref' keyword Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
      "foo": { "type": "string" }
  },
  "$ref": "#/$defs/bar",
  "unevaluatedProperties": false,
  "$defs": {
    "bar": {
      "properties": {
        "bar": { "type": "string" }
      }
    }
  }
}
Valid An instance with no unevaluated properties is valid Instance
{ "foo": "foo", "bar": "bar" }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "foo" ] }
{ "keyword": "/$ref/properties", "instance": "", "value": [ "bar" ] }
Invalid An instance with unevaluated properties is invalid Instance
{ "foo": "foo", "bar": "bar", "baz": "baz" }
Schema with nested 'unevaluatedProperties' keyword Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "foo": { "type": "string" }
  },
  "allOf": [
    {
      "unevaluatedProperties": true
    }
  ],
  "unevaluatedProperties": false
}
Valid No properties remain unevaluated for the top-level 'unevaluatedProperties' Instance
{ "foo": "foo", "bar": 101 }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "foo" ] }
{ "keyword": "/allOf/0/unevaluatedProperties", "instance": "", "value": [ "foo", "bar" ] }