Repository navigation
Description
Description
Description
When $RefParser.bundle() cannot resolve an external $ref, it logs Skipping unresolvable $ref: … and continues — but the $ref string appears to remain in the bundled spec object. Later, @hey-api/shared's parser walks the full schema graph and hard-fails on that same ref:
Reference not found: http://redfish.dmtf.org/schemas/v1/Sensor.yaml#/components/schemas/Sensor_SensorLowerCriticalExcerpt
So bundle treats the ref as skippable, but parse treats it as fatal. Scoped generation (with parser.filters.operations.include) still works because the parser never reaches the affected schema subtree — which is why this only shows up on full / unfiltered generation.
Thanks again for the quick turnaround on #3412 / #3422 — sibling schema hoisting made a huge difference for the DMTF Redfish spec. This feels like a related follow-on on full generation rather than a regression in that fix.
Steps to Reproduce
-
Point
openapi-tsat the current DMTF Redfish OpenAPI document (Version 2026.1):https://github.com/DMTF/Redfish-Publications/blob/c3a8a4c26d92/openapi/openapi.yamlOr live:
https://raw.githubusercontent.com/DMTF/Redfish-Publications/refs/heads/main/openapi/openapi.yaml -
Run full generation — no
REDFISH_SCOPE, noparser.filters.operations.include:openapi-ts
-
Observe console output during bundle:
Skipping unresolvable $ref: http://redfish.dmtf.org/schemas/v1/Sensor.yaml#/components/schemas/Sensor_SensorLowerCriticalExcerpt -
Generation then fails during parse:
Reference not found: http://redfish.dmtf.org/schemas/v1/Sensor.yaml#/components/schemas/Sensor_SensorLowerCriticalExcerpt
For comparison, the 2025.4 spec (commit 26c949654e3e, January 2026) completes full generation successfully on the same toolchain — no Sensor excerpt ref, no failure.
Example chain (Redfish 2026.1)
The dangling ref is a wrapper → versioned redirect inside Sensor.yaml:
# http://redfish.dmtf.org/schemas/v1/Sensor.yaml
Sensor_SensorLowerCriticalExcerpt:
$ref: http://redfish.dmtf.org/schemas/v1/Sensor.v1_9_3.yaml#/components/schemas/Sensor_v1_9_3_SensorLowerCriticalExcerptbundle() fv
Reproducible example or configuration
Minimal config — full mode, no operation filter:
import { defineConfig } from '@hey-api/openapi-ts';
export default defineConfig({
input:
'https://raw.githubusercontent.com/DMTF/Redfish-Publications/refs/heads/main/openapi/openapi.yaml',
output: { path: 'src/client.full' },
plugins: [
'@hey-api/client-axios',
'@hey-api/sdk',
{ name: '@hey-api/typescript', enums: 'javascript' },
],
});Run: openapi-ts (no REDFISH_SCOPE, no parser.filters.operations.include).
OpenAPI specification (optional)
- Fails (2026.1): https://github.com/DMTF/Redfish-Publications/blob/c3a8a4c26d92/openapi/openapi.yaml
- Passes (2025.4): https://github.com/DMTF/Redfish-Publications/blob/26c949654e3e/openapi/openapi.yaml
System information (optional)
@hey-api/openapi-ts: 0.98.2
@hey-api/json-schema-ref-parser: 1.4.3
@hey-api/shared: 0.4.8
Node.js: 22.16.0. <-- note, currently a hard requirement for our project, a lower version than what is pinned for openapi-ts.
Activity
pullfrog commentedon Jun 17, 2026
Fix implemented but push blocked by authentication error:
remote: Invalid username or token. Password authentication is not supported for Git operations.The fix wraps all six
context.resolveRef()calls acrossparseRef()in three parsers (2.0.x, 3.0.x, 3.1.x) with try/catch. When a$refcan't be resolved (external refs that$RefParser.bundle()already skipped), the parser now logsconsole.warn("Skipping unresolvable $ref: ...")and continues instead of hard-failing with"Reference not found".Changes
packages/shared/src/openApi/3.0.x/parser/schema.ts:parseRef()— wrapped bothresolveRefcalls in try/catchpackages/shared/src/openApi/3.1.x/parser/schema.ts:parseRef()— wrapped bothresolveRefcalls in try/catchpackages/shared/src/openApi/2.0.x/parser/schema.ts:parseRef()— wrapped bothresolveRefcalls in try/catchVerification
@hey-api/shared✅Commit is at
b73aac0on branchpullfrog/4084-handle-unresolvable-refs.Task list (8/8 completed)
DeepSeek Pro(free via Pullfrog for OSS) | 𝕏mrlubos commentedon Jun 18, 2026
@pullfrog try again
pullfrog commentedon Jun 18, 2026
Created PR #4087: wrapped all six
context.resolveRef()calls inparseRef()across the 2.0.x, 3.0.x, and 3.1.x parsers with try/catch. When a$refcan't be resolved (external refs that$RefParser.bundle()already skipped), the parser now logsconsole.warn("Skipping unresolvable $ref: ...")and continues instead of hard-failing. All 526@hey-api/sharedtests pass.Task list (8/8 completed)
DeepSeek Pro(free via Pullfrog for OSS) | 𝕏mrlubos commentedon Jun 18, 2026
@j-westover try with the latest
npm i @hey-api/openapi-ts@next, I made it delete those unresolvable references