JSON and data guides

JSON Schema oneOf: validate tagged alternatives

Use const tags to make alternatives exclusive and explain why matching two branches fails oneOf.

Nav Tools ·

Model two different messages

oneOf requires exactly one subschema to validate. A required tag with a different const value in each branch makes that choice explicit.

Start with two synthetic messages rather than inferring a union from a single generated sample.

{"oneOf":[
 {"type":"object","properties":{"kind":{"const":"email"},"to":{"type":"string"}},"required":["kind","to"]},
 {"type":"object","properties":{"kind":{"const":"sms"},"phone":{"type":"string"}},"required":["kind","phone"]}]}

Test one successful branch

An email object with kind email and a string to value satisfies the first branch and fails the sms tag constraint.

Try changing only the tag to sms: a missing phone should now fail. This isolates branch selection from field typing.

{"kind":"email","to":"demo@example.com"} → valid
{"kind":"sms","to":"demo@example.com"} → invalid

Avoid overlapping alternatives

If two branches both accept the same object, oneOf fails even though neither branch reports a local type problem. anyOf instead permits one or more matches.

Choose based on the protocol: exclusive message variants need oneOf; alternative acceptable constraints may need anyOf.

Keep unknown-field policy explicit

The example deliberately does not forbid extra fields. Add additionalProperties false inside each complete object branch if the contract requires it.

Read all validator errors: failures from nonselected branches are expected, but the selected branch must still satisfy its own required fields.

References

← JSON and data guides