Skip to content

openapi: a path item's undeclared key reaches the IR in no form #377

Description

@OmarAlJarrah

Summary

Every OpenAPI object the compiler reads now records the keys the specification
does not define for it, kept under Unmodeled and announced at warning. A Path
Item Object is the one exception, and the reason is upstream: the marshaller
folds a key it does not recognize into the item's embedded operations map rather
than recording it as undeclared, so GetUnknownProperties returns nothing for it
and there is no census to read.

Verified at speakeasy-api/openapi v1.24.0. For

paths:
  /x:
    bogusPathItem: 1
    get: {operationId: getX, responses: {"200": {description: ok}}}

the path item's census is empty, and iterating the item yields two "methods" —
get and bogusPathItem, the latter holding an empty Operation. The scalar 1
reaches the IR in no form.

What is and is not lost

The key is not lost silently, which separates it from every object the census
already covers. Folding it produces

error validation-type-mismatch pathItem.bogusPathItem expected `object`, got `...`

at the key's own pointer, and that validation is unconditional. What is lost is
the key's value, not the fact that it was written.

Why it was not fixed alongside the rest

Recovering the value means reading the item's raw node against a Path Item
Object's key vocabulary. The only method vocabulary this compiler owns is
httpMethods in compilers/openapi/internal/operation/operations.go, which
lists eight; the library's HTTPMethod has nine, including query, the method
OpenAPI 3.2 adds. So the obvious reading — take the keys of the operations map
that httpMethods does not name — reports a valid 3.2 query operation as an
undeclared key:

openapi: 3.2.0
paths:
  /x:
    get:   {operationId: getX, responses: {"200": {description: ok}}}
    query: {operationId: queryX, responses: {"200": {description: ok}}}

Both sit in the same map. Widening httpMethods is what #293 is about
(additionalOperations are dropped entirely today), so settling it here would
settle that issue as a side effect of an unrelated one.

Options

The decision and its reasoning are recorded at applyPathItem in
compilers/openapi/internal/operation/operations.go.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions