Skip to content

parser: boolean component schemas and $ref-form callbacks fail to decode #447

Description

@erraggy

Epic A — Correct the measured conformance defects · Size M · Release v1.60.0 · Blocked by: nothing

Problem

Two valid OAS 3.1+ constructs fail to decode, so the document is rejected before validation runs at all. Both were masked until now: the root-requirement false positive in 433 rejected these fixtures first, so the parse failure never surfaced.

1. A Components schema entry may be a boolean

tests/schema/pass/valid_schema_types.yaml (3.2):

components:
  schemas:
    anything_boolean: true
    nothing_boolean: false
    anything_object: {}
    nothing_object: { not: {} }
cannot construct !!bool `true` into parser.Alias
cannot construct !!bool `false` into parser.Alias

Components.Schemas is map[string]*Schema, but in JSON Schema 2020-12 a schema may be a boolean, and OAS 3.1+ adopts that dialect wholesale. The fixture's comment states it outright: "this example shows that top-level schemaObjects MAY be booleans".

oastools already handles schema-or-bool in the nested positions — Items, AdditionalProperties, AdditionalItems, UnevaluatedItems, UnevaluatedProperties are all any and every decode path promotes them (see CLAUDE.md). components.schemas values were not included in that treatment.

2. A Callback Object used as a Reference fails to decode

tests/schema/pass/path_item_servers_parameters.yaml:44 (3.2):

callbacks:
  transactionCallback:
    $ref: '#/components/callbacks/transactionCallback'
cannot construct !!str `#/compo...` into parser.PathItem

A Callback is map[string]*PathItem keyed by runtime expression. When the Callback is instead a Reference Object, the $ref key is read as a runtime expression and its string value as a Path Item. The schema types this position as callbacks-or-reference, so both forms are valid.

Why these are epic A and not epic D

These are decode-model gaps, so they cannot be fixed by a version gate. They do belong to failure mode A (vocabulary) that D2's matrix drift-guard closes permanently — but epic A's acceptance criterion is 37/37 on the 3.2 positive suite, and these are two of the four remaining failures.

Acceptance

  • pass/valid_schema_types.yaml parses and validates clean; a boolean components.schemas entry round-trips to the same boolean in both JSON and YAML.
  • pass/path_item_servers_parameters.yaml parses and validates clean; a $ref-form Callback round-trips with the reference preserved verbatim.
  • Deep copy and equality treat both forms correctly — per CLAUDE.md, via the generated DeepCopy() methods, never JSON marshal/unmarshal.
  • The boolean form is rejected for OAS 3.0 and 2.0, which do not use the 2020-12 dialect.

Files

parser/oas3.go, parser/schema.go, parser/paths.go, parser/zz_generated_decode.go (regenerated)


Design: 2026-08-01-spec-conformance-gap-design.md · Plan: 2026-08-01-spec-conformance-gap-plan.md

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingconformanceOpenAPI specification conformance workoas3.xIssues related to OpenAPI Specification versions 3+

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions