A schema that declares properties beside a contradictory enum or scalar type lowers to the
enum or the scalar, and the properties are discarded with no diagnostic.
openapi: 3.1.0
info: {title: p, version: "1"}
paths:
/u:
post:
requestBody:
content:
multipart/form-data:
schema:
type: string
enum: [a, b]
properties:
f: {type: string, format: binary}
responses: {"200": {description: ok}}
The node lowers to kind: enum with unmodeled: null. Nothing records that properties was
written, and nothing reports it.
The schema is contradictory — an instance cannot be both a string from a two-member enum and an
object with an f property — so lowering to one of the two is a reasonable degradation. Silently
discarding the other half is not: ir-design.md §4.8 requires a degraded lowering to keep the
original beside it so the loss stays recoverable.
How it surfaces
Indirectly, and confusingly. partEncodings mints an encoding key for the binary part it can see
in the source, but the lowered node holds no properties, so the new encoding-key check reports the
key as addressing nothing:
error ir/encoding-key-unknown-property … encoding key "…/schema/properties/f" … addresses no
property of the content type "t/anon/…/schema"
That diagnostic is correct about what it checks and points at the wrong thing: the defect is the
dropped properties, not the key.
Suggested shape
Keep the unlowered half verbatim under ReasonDegradedLowering with a diagnostic naming which
half was taken, the way a oneOf co-declared with structural keywords already does. A reader then
gets one diagnostic about the real problem instead of one about a downstream symptom.
Method
Compiled through openapi.New().Compile(...), inspecting the emitted node and the full diagnostic
list.
A schema that declares
propertiesbeside a contradictoryenumor scalartypelowers to theenum or the scalar, and the properties are discarded with no diagnostic.
The node lowers to
kind: enumwithunmodeled: null. Nothing records thatpropertieswaswritten, and nothing reports it.
The schema is contradictory — an instance cannot be both a string from a two-member enum and an
object with an
fproperty — so lowering to one of the two is a reasonable degradation. Silentlydiscarding the other half is not:
ir-design.md§4.8 requires a degraded lowering to keep theoriginal beside it so the loss stays recoverable.
How it surfaces
Indirectly, and confusingly.
partEncodingsmints an encoding key for thebinarypart it can seein the source, but the lowered node holds no properties, so the new encoding-key check reports the
key as addressing nothing:
That diagnostic is correct about what it checks and points at the wrong thing: the defect is the
dropped
properties, not the key.Suggested shape
Keep the unlowered half verbatim under
ReasonDegradedLoweringwith a diagnostic naming whichhalf was taken, the way a
oneOfco-declared with structural keywords already does. A reader thengets one diagnostic about the real problem instead of one about a downstream symptom.
Method
Compiled through
openapi.New().Compile(...), inspecting the emitted node and the full diagnosticlist.