unevaluatedItems : Schema
unevaluatedItems
SchemaValidates array elements that did not successfully validate against other standard array applicators.
Value | This keyword must be set to a valid JSON Schema |
---|---|
Kind | Applicator Annotation |
Applies To | Array |
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.2 |
Metaschema | https://json-schema.org/draft/2020-12/meta/unevaluated |
Official Tests | draft2020-12/unevaluatedItems.json |
Default |
{}
|
Annotation | Boolean A boolean true if it applied to any item of the instance |
Affected By |
|
Affects | None |
Also See |
|
If no relevant annotations are present, the unevaluatedItems
subschema must be applied to all locations in the array. If a boolean true value is present from any of the relevant annotations, unevaluatedItems
is ignored. Otherwise, the subschema must be applied to any index greater than the largest annotation value for prefixItems
, which does not appear in any annotation value for contains
.
Evaluation
It’s crucial to understand what evaluation means in this context.
unevaluatedItems
considers annotations from prefixItems
, items
, and contains
, both as adjacent keywords and in subschemas of adjacent keywords. Additionally, it is also affected by other unevaluatedItems
in nested schemas (if present).
- The keywords
prefixItems
,items
,contains
andunevaluatedItems
produce annotations for the indexes they successfully validate against. - If any of these keywords generate an annotation for a particular index, that index is considered as evaluated.
- By definition, the
unevaluatedItems
subschema is always applied afterprefixItems
,items
, andcontains
subschemas. - As its name implies,
unevaluatedItems
applies to any array index that has not been previously evaluated.
Examples
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"unevaluatedItems": true
}
[ "foo", "bar" ]
{ "keyword": "/unevaluatedItems", "instance": "", "value": "true" }
"John Doe"
- Here, no items are defined in the above schema. Consequently, all items in an array instance are considered unevaluated, and the
unevaluatedItems
subschema applies to them. Since the subschema here is a boolean true, an instance with unevaluated items, regardless of their value, is considered valid.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"unevaluatedItems": false
}
[ "foo", "bar" ]
{ "John": 46 }
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"prefixItems": [ { "type": "string" } ],
"contains": { "type": "number" },
"unevaluatedItems": false
}
[ "foo", 101, false ]
[ "foo", 101, 77 ]
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
{ "keyword": "/contains", "instance": "", "value": [ 1, 2 ] }
-
For the first instance, the annotation result of
prefixItems
is 0, and the annotation result ofcontains
is [ 1 ]. However, the item at 2nd index (i.e.,false
) remains unevaluated, so theunevaluatedItems
subschema applies to it. This subschema fails (as any instance against a false schema is always invalid), leading to validation failure. -
For the second instance, the annotation result of
prefixItems
is 0, and the annotation result of contains is [ 1, 2 ]. No items remain unevaluated; hence, the instance is considered valid.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"prefixItems": [ { "type": "string" } ],
"contains": { "type": "number" },
"unevaluatedItems": { "type": "boolean" }
}
[ "foo", 101, 77 ]
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
{ "keyword": "/contains", "instance": "", "value": [ 1, 2 ] }
[ "foo", 101, false ]
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
{ "keyword": "/contains", "instance": "", "value": [ 1 ] }
{ "keyword": "/unevaluatedItems", "instance": "", "value": true }
[ "foo", 101, [ false ] ]
-
For the first instance, there are no unevaluated items.
-
For the second instance, the item at 2nd index (i.e.,
false
) remains unevaluated, and theunevaluatedItems
subschema applies to it. This item conforms to this subschema, and hence the instance is valid.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"prefixItems": [ { "type": "string" } ],
"allOf" : [
{
"prefixItems": [
true,
{ "type": "boolean" }
]
}
],
"unevaluatedItems": { "type": "number" }
}
[ "foo", false, 22 ]
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
{ "keyword": "/allOf/0/prefixItems", "instance": "", "value": 1 }
{ "keyword": "/unevaluatedItems", "instance": "", "value": true }
[ "foo", 101, [ false ] ]
For the above two instances, the annotation result of top level prefixItems
is 0, and the annotation result of the nested prefixItems
is 1. The unevaluatedItems
recognizes the annotations from top level prefixItems
as well as nested prefixItems
(as it can see through adjacent and nested applicators as only the produced annotations matter, not the schema structure) and ensures that the item at index 2 remains unevaluated and its subschema applies to it.
- 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": "https://json-schema.org/draft/2020-12/schema",
"prefixItems": [ { "type": "string" } ],
"allOf" : [
{
"items": true
}
],
"unevaluatedItems": { "type": "number" }
}
[ "foo", false, 22 ]
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
{ "keyword": "/allOf/0/items", "instance": "", "value": true }
- Here, the nested
items
evaluated all the unevaluated items. So there’s nothing left unevaluated.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"prefixItems": [
{ "type": "string" },
{ "type": "boolean" }
],
"$ref": "#/$defs/bar",
"unevaluatedItems": false,
"$defs": {
"bar": {
"contains": { "type": "number" }
}
}
}
[ "foo", false, 22 ]
{ "keyword": "/prefixItems", "instance": "", "value": 1 }
{ "keyword": "/$ref/contains", "instance": "", "value": [ 2 ] }
[ "foo", false, "bar" ]
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"prefixItems": [ { "type": "string" } ],
"allOf" : [
{
"unevaluatedItems": true
}
],
"unevaluatedItems": false
}
[ "foo", false, "bar" ]
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
{ "keyword": "/allOf/0/unevaluatedItems", "instance": "", "value": true }