Description
Describe the inspiration for your proposal
I want to enforce that "nothing goes unseen" by the schema - for example to safeguard against misspelled property names, ensure that extension properties follow a naming convention, to prevent instances from adding bespoke properties that would subvert interoperability requirements, or otherwise enforce that the instance is 100% covered by the schema.
additional*
items/properties don't meet the need because our schemas are large and use $ref
and/or allOf
to aggregate component subschemas from a schema registry.
unevaluated*
items/properties don't meet the need because because properties are considered "unevaluated" even if they are expected, required, and valid, if they are within a failing subschema. This causes very many false negative failed validations, often many layers removed from the actual invalid property/item. See also #1604, which this new keyword would resolve.
Describe the proposal
A new keyword pair for undefined*
properties and items might work alongside the unevaluated*
and additional*
keywords.
additional*
and unevaluated*
keywords distinguish if a property/item successfully validates. undefined*
rather distinguishes if the property/item has an applicable definition. See also #1605, which this new keyword would resolve.
A property/item can be called "defined" if it produces a validation result or annotations in the schema being evaluated or any applicable sub-schema.
- The schema being evaluated is of course applicable to itself.
- A subschema of the schema being evaluated is always applicable if it is required by it's applicator, whether or not the subschema or the applicator are valid.
- For example,
allOf
and$ref
require every subschema to be valid. - If
if
, thenthen
is "required", elseelse
is. The "requirement" is external to thethen
/else
applicator. - No
oneOf
/anyOf
subschema is required, because the applicator could still be valid even if the subschema were invalid, as long as another subschema were valid. - The
if
subschema is not required, sinceif
is valid even with a falsy subschema. not
is the opposite of required.
- For example,
- An evaluated subschema of the schema being evaluated is applicable, even if not required by it's applicator, if it is valid.
- All of the valid
anyOf
subschemas are applicable. - The
if
subschema is applicable if it's valid - I think, but I'm not sure, that a valid
not
schema is applicable. That's whynot
complains - it shouldn't be applicable, but it is. then
orelse
subschemas aren't evaluated if not selected byif
, so they aren't applicable even if they would be valid.
- All of the valid
Describe alternatives you've considered
A boolean flag like closed
or final
might have similar effect to {"undefinedProperties": false}
, but consistency between undefined*
, unevaluated*
, and additional*
items/properties makes more sense.
Additional context
Annotations are currently gathered for evaluated
items/properties - I think because this is the closest existing method to determining if the annotations are applicable. This change might help to collect more applicable annotations by including annotations from any defined
property/item. But this might not be desired, depending on if a failed validation is considered "not an instance" vs. "a malformed instance" of the schema.