Skip to content

openapi: reference-resolution failures are reported without a source location #235

Description

@OmarAlJarrah

Problem

Every unresolved-reference diagnostic the lowering emits points at the position that wrote the reference. The ones the resolve phase emits do not — they carry an empty pointer:

error openapi/unresolved-ref  ptr=""                      external reference not allowed
error openapi/unresolved-ref  ptr=/components/schemas/A   unresolved $ref "c.yaml#/components/schemas/X"

A document with several unresolvable references produces several findings that all name the document and none of them the site, so there is nothing to act on.

It stems from ResolveAllReferences running in compilers/openapi/internal/load/load.go before the walk that would know a position, and from the library returning bare errors.New values with no location attached.

Why it is not cosmetic

Six reference positions have no sited diagnostic at all — the unsited one is their only report. Compiling a spec whose $ref at each position names a missing component, each in turn:

position sited diagnostic unsited
component schema, property, allOf branch, items, oneOf variant, securityScheme, discriminator mapping yes yes
pathItem, parameter, response, requestBody, header, callback no yes

So the unsited diagnostic cannot simply be dropped as a duplicate; it has to be replaced by a sited one.

It also forces a compromise in the load phase today: identical resolver failures are collapsed into one diagnostic, because without a site N of them genuinely carry no more information than one. Once each names its site they are distinct findings and should separate.

Direction

The resolve phase needs a position for each failure. Two candidate sources:

  • soa.Walk yields a WalkItem.Location alongside each resolvable, and ResolveAllReferences is itself a Walk + resolve loop — driving that walk directly keeps the location that the library's own helper discards.
  • A raw-YAML scan for $ref values, in the shape internal/scan already uses for cycle detection, which would also carry line:col.

Acceptance

  • Each unresolvable reference is reported once, at the pointer that wrote it, whatever its position.
  • The six positions above stop depending on a document-level diagnostic.
  • The identical-message collapse in resolveDiags comes out.

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