You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Component schemas (/components/schemas/<name>) are interned under a name-derived ID and resolve to one node however many times they are referenced. Every other component type — parameters, requestBodies, responses, headers, examples, callbacks, pathItems — is lowered at its use-site pointer instead. resolveRef swaps the referenced object's content in, but the pointer handed to the lowering call still describes the $ref site, which has no children of its own. The result is the same three failures #36 fixed for path-item-level parameters, but reached through references rather than through the path-item merge:
Provenance points at nothing. A $ref site is a one-key object; <ref-site>/schema, <ref-site>/content/..., and <ref-site>/headers/... do not exist in the source document.
IDs are not derived from the declaration's pointer (invariant 3). They are derived from where the reference happens to be written, so the same declaration yields a different ID per use site.
One declaration hoists once per use site instead of interning once.
Reproduction
Two operations referencing the same four components:
None of those eight pointers exists in the document. /paths/~1a/get/parameters/0 holds {$ref: ...} and has no schema child; the real location is /components/parameters/Page/schema. The header case compounds twice over — /paths/~1a/get/responses/200/headers/X-Rate/schema is a fabricated path through a referenced response into a referenced header, whose actual declaration is /components/headers/Rate/schema.
Referenced path items behave the same way: /a: {$ref: '#/components/pathItems/Shared'} and /b: {$ref: '#/components/pathItems/Shared'} hoist the shared path item's parameter schemas twice, under /paths/~1a/... and /paths/~1b/....
Root cause
Every lowering site composes its child pointers from the pointer it was called with, which is always the use site, while resolveRef independently supplies the referenced object's content:
Nothing in this chain consults whether the object it is lowering arrived inline or through a $ref.
Expected
A referenced component is lowered at the pointer it is declared at, so its ID is stable across use sites and it interns once — the same guarantee /components/schemas/<name> already has. Provenance must reference locations that exist in the source document.
Worth deciding as part of this: whether a referenced non-schema component should get a named ID (as namedTypeID gives component schemas) or stay anonymous with a declaration-site pointer. The Naming on the resulting node differs between the two.
Cross-document $refs are already dropped with a diagnostic and are not part of this.
Summary
Component schemas (
/components/schemas/<name>) are interned under a name-derived ID and resolve to one node however many times they are referenced. Every other component type —parameters,requestBodies,responses,headers,examples,callbacks,pathItems— is lowered at its use-site pointer instead.resolveRefswaps the referenced object's content in, but the pointer handed to the lowering call still describes the$refsite, which has no children of its own. The result is the same three failures #36 fixed for path-item-level parameters, but reached through references rather than through the path-item merge:$refsite is a one-key object;<ref-site>/schema,<ref-site>/content/..., and<ref-site>/headers/...do not exist in the source document.Reproduction
Two operations referencing the same four components:
Four declarations, each written exactly once, produce eight hoisted types:
None of those eight pointers exists in the document.
/paths/~1a/get/parameters/0holds{$ref: ...}and has noschemachild; the real location is/components/parameters/Page/schema. The header case compounds twice over —/paths/~1a/get/responses/200/headers/X-Rate/schemais a fabricated path through a referenced response into a referenced header, whose actual declaration is/components/headers/Rate/schema.Referenced path items behave the same way:
/a: {$ref: '#/components/pathItems/Shared'}and/b: {$ref: '#/components/pathItems/Shared'}hoist the shared path item's parameter schemas twice, under/paths/~1a/...and/paths/~1b/....Root cause
Every lowering site composes its child pointers from the pointer it was called with, which is always the use site, while
resolveRefindependently supplies the referenced object's content:params.gofillParamType—schemaPtr := pptr + ptr("schema")content.golowerRequestBody:210—bodyPtr := opPointer + ptr("requestBody")content.golowerHeaders:144—hptr := basePtr + ptr("headers", name), which also feedspropID(hptr), so headerPropIDs are affected as well asTypeIDsoperations.golowerResponses:285—rptr := opPointer + ptr("responses", code)operations.golowerCallbacks:395—opPointer + ptr("callbacks", cbName, exprStr)Nothing in this chain consults whether the object it is lowering arrived inline or through a
$ref.Expected
A referenced component is lowered at the pointer it is declared at, so its ID is stable across use sites and it interns once — the same guarantee
/components/schemas/<name>already has. Provenance must reference locations that exist in the source document.Notes
namedTypeIDgives component schemas) or stay anonymous with a declaration-site pointer. TheNamingon the resulting node differs between the two.$refs are already dropped with a diagnostic and are not part of this.