A discriminator mapping may spell two wire values for one subtype — an alias tag. The compiler
keeps both on the base and picks one for the subtype, and which one it picks depends on the
order the keys are written in.
Reproduction
openapi: 3.1.0
info: {title: T, version: "1"}
paths: {}
components:
schemas:
Pet:
type: object
required: [k]
properties: {k: {type: string}}
discriminator:
propertyName: k
mapping:
alpha: '#/components/schemas/Dog'
zulu: '#/components/schemas/Dog'
Dog:
allOf: [{$ref: '#/components/schemas/Pet'}]
properties: {bark: {type: boolean}}
$ morphic compile dd.yaml -skip-validate | jq -r '.types["t/openapi/components/schemas/Dog"].discriminatorValue'
alpha
Swap the two mapping lines and nothing else, and the same document lowers to zulu. No
diagnostic is emitted in either case.
Why it is a defect rather than a preference
A JSON or YAML mapping is unordered, so those two files are the same document. Lowering them
differently is the property the order-invariance oracle exists to reject — it would reject this
one, except that no committed spec declares two keys for one target, so the oracle never meets
the shape.
The scope is narrower than it first looks, and worth stating: nothing is lost. Discriminator
on the base keeps the whole mapping, both keys included, so the routing table an emitter needs
is intact. What varies is Model.DiscriminatorValue, the per-subtype convenience field, which
structurally holds one value and so cannot represent an alias pair at all.
Expected
Two documents differing only in mapping key order lower identically. Whether that means
choosing the tag by a rule that does not depend on declaration order, or reporting the pair as
a degradation because the field cannot hold both, is the decision to take here — the silent
order-dependence is what should not survive it.
Pre-existing: the same behaviour is on main before and after #368, which only changed how far
up the chain the mapping is searched.
A discriminator mapping may spell two wire values for one subtype — an alias tag. The compiler
keeps both on the base and picks one for the subtype, and which one it picks depends on the
order the keys are written in.
Reproduction
Swap the two mapping lines and nothing else, and the same document lowers to
zulu. Nodiagnostic is emitted in either case.
Why it is a defect rather than a preference
A JSON or YAML mapping is unordered, so those two files are the same document. Lowering them
differently is the property the order-invariance oracle exists to reject — it would reject this
one, except that no committed spec declares two keys for one target, so the oracle never meets
the shape.
The scope is narrower than it first looks, and worth stating: nothing is lost.
Discriminatoron the base keeps the whole mapping, both keys included, so the routing table an emitter needs
is intact. What varies is
Model.DiscriminatorValue, the per-subtype convenience field, whichstructurally holds one value and so cannot represent an alias pair at all.
Expected
Two documents differing only in mapping key order lower identically. Whether that means
choosing the tag by a rule that does not depend on declaration order, or reporting the pair as
a degradation because the field cannot hold both, is the decision to take here — the silent
order-dependence is what should not survive it.
Pre-existing: the same behaviour is on
mainbefore and after #368, which only changed how farup the chain the mapping is searched.