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.
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"} → invalidAvoid 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.