Skip to content

openapi: several source details silently dropped, violating lossless-by-default #39

Description

@OmarAlJarrah

Summary

A sweep of the operation/parameter/content lowering found six distinct places where declared source content disappears with no IR representation, no Extensions preservation, and no diagnostic. Individually small, they all break the same invariant (lossless by default — a compiler must never drop a capability), so they're grouped here; each was reproduced independently.

  1. Response-header metadata (content.go:146-167, lowerHeaders): headers lower to ir.Property with only ID/Name/WireName/Type/Required/Provenance. description, deprecated, style/explode, examples, extensions, and content-form headers are all dropped — even though ir.Property has Docs/Deprecation/Examples/Extensions fields sitting empty.
  2. Webhook and callback path-item servers (operations.go:119-149, 410-429): applyPathServers (preserve + info diagnostic) is called only from lowerPathItem; webhook and callback path items lose their servers entirely — inconsistent with the path route.
  3. allowEmptyValue (params.go:38-56): every other Parameter field is captured; this one is read nowhere.
  4. Reserved header parameters (params.go:16-33): the spec says header params named Accept/Content-Type/Authorization "SHALL be ignored"; the compiler lowers them as regular logical params + header bindings with no marker. Emitters would generate a user-supplied Authorization parameter that fights the auth scheme. If keeping them is a deliberate lossless choice, it needs an Inferred/diagnostic marker; today it's a silent deviation.
  5. Single-media-type error responses lose the media type (operations.go:355-376, fillErrorType): with >1 media types the whole content map is preserved raw + diagnostic; with exactly one (e.g. application/problem+json) only the schema survives as ErrorCase.Type — the media type string is dropped, asymmetric with the multi-entry path.
  6. Sibling constraints next to a component-level $ref (schema.go:75-82 via componentConstraints): in the 2020-12 dialect keywords beside $ref apply conjunctively. Property positions handle this, but a component whose body is $ref + constraints (Bounded: {$ref: ..., minimum: 5}) interns an alias Scalar with Constraints=nil.

Expected

Each item either lowers into its existing IR field (1, 5, 6 have obvious homes), is preserved under Extensions with a degraded-construct diagnostic (2), or gets an explicit documented policy with a marker (3, 4). None may remain silent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions