Skip to content

openapi: an anchor-valued declared entry — a path item, response, callback or method — is dropped by the fold in silence #459

Description

@fuad-daoud

The bundled library skips a mapping entry whose value carries a YAML anchor before folding the mapping into its model (speakeasy-api/openapi v1.24.1, marshaller/unmarshaller.go: valueNode.Anchor != "" && !strings.HasPrefix(key, "*")). #412 closed the half of that where the skipped key is undeclared: the path-item census now reads the raw mapping and keeps the key verbatim. The other half is worse and still open: when the skipped entry is one the specification declares, the compiler has nothing to lower and says nothing.

Reproduction

Each of these compiles clean, exits 0, and the anchored entry appears nowhere in the IR:

paths:
  /x: &item                       # a whole path item
    get: {operationId: getX, responses: {"200": {description: ok}}}
paths:
  /x:
    get: &g                       # a method on a path item
      operationId: getX
      responses: {"200": {description: ok}}
responses:
  "200": {description: ok}
  "404": &r404 {description: NOTFOUNDANCHORED}    # a response

A callback expression whose value is anchored is dropped the same way. In each case the whole operation — or response, or callback — with every parameter, body, and type reachable only through it, reaches the IR in no form, with no diagnostic. Two documents differing only in the anchor compile to different IR, and the one with less is the one that was written with more.

Why #412's fix does not reach it

#412 preserves: an undeclared key has no lowering, so keeping it verbatim under Unmodeled is the whole answer. A declared entry needs lowering — the compiler must build the operation/response the library never handed it — so the remedy is different, and the sites are different: the embedded-map branch of every core model that carries one (Paths, PathItem's methods, Responses, Callback), not the undeclared-key census.

What would close it

Either lower the anchored entry from its raw node (the raw readers exist; the lowering entry points take the library's model, so this is a bridge per site), or — as the minimum — detect the skip at each embedded-map site by diffing raw keys against folded keys, as #412 now does for the path item, and report a degraded-construct error naming the entry, so the loss is at least not silent. The second is the cheap version and turns a silent drop into a refused document; the first is the lossless one.

Found by the mechanism sweep in #458; the response case was confirmed by an independent probe during its review.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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