2026-09-17 · 6 min read · Rahul Chitturi
- json-schema
- validation
- api-design
A composed JSON Schema can reject an apparently declared property when object closure is applied in the wrong subschema. additionalProperties acts where it is written, while unevaluatedProperties can account for properties successfully evaluated by other applicable schema branches.
The outcome depends on the schema draft, reference handling, branch success, and validator support. Copying a keyword into an older draft does not add the newer evaluation model.
Identify which schema evaluated each property
Reduce the schema and instance to one property at a time. Record declarations reached through properties, patternProperties, applicable conditionals, references, and successful composition branches before interpreting an unevaluatedProperties error.
- Confirm the declared $schema dialect.
- Use the same validator version and options as production.
- Resolve references against the correct base URI.
- Do not treat annotations from a failing branch as successful evaluation.
Place object closure at the intended boundary
Use additionalProperties when a single object schema owns all allowed names. Use unevaluatedProperties when a supported draft composes property declarations across subschemas and closure belongs after that composition.
Be explicit about extension points. A reusable base schema that closes itself cannot usually be extended later through allOf merely by listing more properties in another branch.
Compare minimal validation fixtures
Use the JSON formatter for schemas and instances, diff for validator outputs, URL tool for reference identifiers, and case converter to expose accidental property-name changes.
Test allOf, anyOf, oneOf, if-then-else, dependent schemas, local and remote references, pattern matches, failed branches, nested objects, draft changes, unknown fields, and generated client payloads.