fix: resolve $ref siblings during bundling#2772
Conversation
🦋 Changeset detectedLatest commit: 3fee16d The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
2f635d9 to
60ef033
Compare
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
@cursor review |
|
📦 A new experimental 🧪 version v0.0.0-snapshot.1777378978 of Redocly CLI has been published for testing. Install with NPM: npm install @redocly/cli@0.0.0-snapshot.1777378978
# or
npm install @redocly/openapi-core@0.0.0-snapshot.1777378978
# or
npm install @redocly/respect-core@0.0.0-snapshot.1777378978 |
81fe95d to
03fdf9a
Compare
2051968 to
b8066fb
Compare
| } | ||
|
|
||
| if (isRef(node[propName]) && propType?.name === 'scalar') { | ||
| if (!isNamedType(propType)) { |
There was a problem hiding this comment.
to avoid duplication in the two checks below
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3fee16d. Configure here.
| continue; | ||
| } | ||
|
|
||
| if (!isNamedType(propType) || (propType.name === 'scalar' && !isRef(value))) { |
There was a problem hiding this comment.
Sibling walked with propType derived from resolved value
Medium Severity
When a property exists in both the resolved $ref target and as a sibling, value is set to resolvedNode[propName] (line 326) and propType is computed from that resolved value (line 337). But when the sibling check at line 360 fires, node[propName] (the sibling) is walked with this propType. For function-based type resolvers like additionalProperties (returns { type: 'boolean' } for false vs 'Schema' for objects) or items (returns listOf('Schema') for arrays vs 'Schema' for objects), the sibling value can end up walked with the wrong type. This is visible in the E2E snapshot where additionalProperties: {$ref: reference.yaml} is inlined while identical refs at second and third.items are bundled as component references — an inconsistency caused by the sibling being walked as scalar instead of Schema.
Reviewed by Cursor Bugbot for commit 3fee16d. Configure here.


What/Why/How?
Fixed bundling for $ref siblings so sibling properties are resolved reliably, including nested external refs and non-Schema sibling contexts.
Important
Bundling now resolves all sibling properties next to
$ref, regardless of whether the node is interpreted as a Reference Object or a Schema Object.This is important because OpenAPI 3.1 distinguishes these cases in the spec:
Reference
OpenAPI 3.1 — Reference Object
bundle#1329Testing
Screenshots (optional)
Check yourself
Security
Note
Medium Risk
Touches core
walktraversal/ref-resolution logic used by bundling, which could subtly affect how referenced nodes are visited and resolved across specs. Risk is mitigated by added unit and e2e coverage for nested/external$refsibling cases.Overview
Fixes bundling so sibling keys next to a
$refare traversed and resolved reliably, including when the parent node is treated as a Reference Object and when sibling values contain nested external refs.This introduces
refHasSiblingto precisely detect sibling presence and updateswalkto visit sibling properties on$refnodes based on that check while preserving wrapper fields (e.g.,readOnly,description). Adds new unit fixtures/tests and an e2eref-siblingsscenario (bundled and--dereferenced) to lock in the expected output.Reviewed by Cursor Bugbot for commit 3fee16d. Bugbot is set up for automated code reviews on this repo. Configure here.