OpenAPITools / OpenAPITools/openapi-generator
[BUG] Cannot parse OpenAPI 3.1 specs using $dynamicRef / $dynamicAnchor (blocked by swagger-parser)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Summary
OpenAPI Generator fails to parse any OpenAPI 3.1 spec that uses $dynamicRef / $dynamicAnchor (JSON Schema 2020-12). The parser throws SpecValidationException: Could not find /components/schemas/<name> because swagger-parser cannot resolve schemas containing $dynamicAnchor when the enclosing schema also has $id.
Reproduction
Minimal fixtures demonstrating the issue:
- Recursive category tree: https://github.com/aqeelat/openapi-dynamicref-adoption-tracker/blob/main/fixtures/recursive-category-tree.yaml
- Nested workspace resources: https://github.com/aqeelat/openapi-dynamicref-adoption-tracker/blob/main/fixtures/nested-workspace-resources.yaml
- Pagination/generic wrapper (named schemas): https://github.com/aqeelat/openapi-dynamicref-adoption-tracker/blob/main/fixtures/generic-schema-binding.yaml
npx @openapitools/openapi-generator-cli generate \
-i https://raw.githubusercontent.com/aqeelat/openapi-dynamicref-adoption-tracker/main/specs/recursive-category-tree/oas-3.1.2.json \
-g typescript-fetch \
-o /tmp/dynamicref-test
Result: SpecValidationException: Could not find /components/schemas/PaginatedTemplate
Note: The paginated-response.yaml variant (inline response binding, no named wrappers with $dynamicAnchor) parses successfully, but still produces unknown[] types — the $dynamicRef is not resolved to concrete types.
Root Cause
The failure occurs in swagger-parser (v2.1.41), not in openapi-generator's codegen layer. The OAS 3.1 dereferencer (OpenAPIDereferencer31) has two bugs:
$idhijacks$refresolution: When a component schema has$id, the dereferencer resolves#/components/schemas/...refs against the$idURI instead of the document root, causing a crash.$dynamicRef/$dynamicAnchornot preserved: These fields are deserialized but lost during the dereference cycle.$defsis stored as raw extensions and not traversed.
A fix PR is open: https://github.com/swagger-api/swagger-parser/pull/2332
Expected Behavior
After the swagger-parser fix is merged and openapi-generator updates its dependency:
- Specs with
$dynamicRef/$dynamicAnchorshould parse without errors. - The codegen layer should then be updated to preserve
$dynamicRefsemantics — resolving dynamic refs to concrete types instead ofunknown[]/any.
Blocking Dependency
- https://github.com/swagger-api/swagger-parser/pull/2332 — fixes
$id/$refinteraction and preserves$dynamicRef/$dynamicAnchorthrough parsing
Once swagger-parser merges this fix, openapi-generator will need to:
- Bump the swagger-parser dependency version
- Add codegen-level changes to resolve
$dynamicRefto concrete schema types during type emission
Compatibility Evidence
A cross-generator compatibility matrix is tracked at:
https://github.com/aqeelat/openapi-dynamicref-adoption-tracker
Related: #13087 (closed without implementation)
This issue was drafted with assistance from AI tooling. The submitter is responsible for reviewing and validating the contents before submission.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided npx reproduction using the recursive-category-tree fixture and confirm the parser failure. Track swagger-parser PR #2332, then inspect the dependency update and codegen type-emission path once it is available. Done means the named fixtures parse and dynamic references produce concrete types rather than unknown[] or any.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100