Skip to content

openapi: the cycle pre-scan's merge-bound warning depends on declaration order #402

Description

@OmarAlJarrah

refScan (compilers/openapi/internal/scan/scan.go:304) builds one nodeview.View and shares it across the whole pre-scan. nodeview memoizes a mapping's merge expansion, so a node first expanded shallowly is later served from that memo to a walk that reaches it deeper than MergeDepthLimit would allow. Whether the bound is hit therefore depends on which schema the scan reached first.

The bound being hit sets View.Exhausted(), which scan.go:174 reports as openapi/cycle-scan-failed. So the same document emits that warning in one declaration order and not the other.

Reproducer

One document, two orders. Anchors c0..c50 form a 51-link chain with d0..d20 riding on c50 (71 total, past the 64 bound); schema P merges *c50, schema Q merges *d20.

Declared P-then-Q, the c-chain is memoized shallowly and Q's deeper reach is answered from cache, so the bound is never hit. Declared Q-then-P, Q expands first and truncates, and the compile gains:

warning openapi/cycle-scan-failed: cycle pre-scan stopped at its 64-level merge-key expansion bound;
  reference-cycle protection is incomplete for this source

The exact generator is mergeBoundOrderSpec in compilers/openapi/internal/schema/schema_test.go, added by #362.

Why the sweep does not catch it

The construct needs YAML anchors, and internal/harness's reverseMappings declines to permute a document whose aliases the reversal would lift above their anchors — so orderInvariant returns ok without ever comparing. Filed separately as the oracle blind spot.

Impact is a diagnostic rather than the IR: the warning says cycle protection is incomplete, and it appears or not depending on source order. Found while probing #362, which had the same mechanism in the resource-boundary walk and reverted it.

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