A boolean false schema matches no instance. It lowers to a closed empty Model
(compilers/openapi/internal/schema/schema.go, falseSchema), which matches the empty JSON
object:
components:
schemas:
F: false
t/openapi/components/schemas/F -> {"kind":"model","additional":"closed"}
info openapi/false-schema /components/schemas/F: boolean false schema matches nothing;
lowered as a closed empty model
A model with no properties and additionalProperties: false accepts {} and rejects everything
else. The source accepts nothing at all, so the lowered type admits exactly one value the source
forbids — a small overstatement, but the same kind of overstatement the false rule exists to
avoid, and an emitter reading the node has no way to tell "no instance" from "the empty object".
Why this is worth revisiting now rather than when it was decided
When #154 settled this, the closed empty Model was the nearest shape the IR had, and
ir-design.md §4.8 records it as the normative lowering. That is no longer the nearest shape: a
closed Enum with no members is an exactly empty value space — it admits its members and has
none — and #278 now uses it for enum: [], with §4.5 stating the reading. So one document can
carry two constructs that both match nothing, lowered to two shapes, only one of which is exact.
Scope
falseSchema (a false schema in its own right, and at a $ref/branch position via
schemaRefHomed).
applyFalseBranches (the §4.8 rule for a false allOf conjunct), which closes the composed
model rather than emptying it — that half is deliberate and documented, and a change here has to
say what happens to the other branches' properties before it moves.
Both are normative in ir-design.md §4.8, so this is a documentation change as much as a code one:
either the closed empty Model stays and §4.8 says why an approximation is preferred, or the rule
moves to the exact shape and §4.8 and §4.5 agree on one spelling of "matches nothing".
Method
Noticed while lowering enum: [] for #278, where the same question had to be answered for a
different keyword. Not fixed there: the false rule is normative and reaches composition, so it is
its own decision rather than a side effect of the enum one.
A boolean
falseschema matches no instance. It lowers to a closed emptyModel(
compilers/openapi/internal/schema/schema.go,falseSchema), which matches the empty JSONobject:
A model with no properties and
additionalProperties: falseaccepts{}and rejects everythingelse. The source accepts nothing at all, so the lowered type admits exactly one value the source
forbids — a small overstatement, but the same kind of overstatement the
falserule exists toavoid, and an emitter reading the node has no way to tell "no instance" from "the empty object".
Why this is worth revisiting now rather than when it was decided
When #154 settled this, the closed empty
Modelwas the nearest shape the IR had, andir-design.md§4.8 records it as the normative lowering. That is no longer the nearest shape: aclosed
Enumwith no members is an exactly empty value space — it admits its members and hasnone — and #278 now uses it for
enum: [], with §4.5 stating the reading. So one document cancarry two constructs that both match nothing, lowered to two shapes, only one of which is exact.
Scope
falseSchema(afalseschema in its own right, and at a$ref/branch position viaschemaRefHomed).applyFalseBranches(the §4.8 rule for afalseallOfconjunct), which closes the composedmodel rather than emptying it — that half is deliberate and documented, and a change here has to
say what happens to the other branches' properties before it moves.
Both are normative in
ir-design.md§4.8, so this is a documentation change as much as a code one:either the closed empty
Modelstays and §4.8 says why an approximation is preferred, or the rulemoves to the exact shape and §4.8 and §4.5 agree on one spelling of "matches nothing".
Method
Noticed while lowering
enum: []for #278, where the same question had to be answered for adifferent keyword. Not fixed there: the
falserule is normative and reaches composition, so it isits own decision rather than a side effect of the enum one.