Failing test: OAS 3.1 internal $ref inlined when spec loaded by file:// URL (resolveFully=false) — #1922#2342
Draft
pavelkryl wants to merge 1 commit into
Draft
Conversation
…ef lost on file:// URL load
For an OAS 3.1 doc with only internal ("#/components/...") references parsed with
resolve=true and resolveFully=false, the internal $refs must be preserved regardless
of whether the root document is loaded by filesystem path or by file:// URL.
Today they diverge: loaded by path the $ref is preserved; loaded by file:// URL the
3.1 dereferencer inlines the referenced schema and the $ref is lost. Downstream code
generators (openapi-generator, quarkus-openapi-generator) that hand the spec to the
parser as a URL therefore duplicate every reused component per use-site and leave the
canonical component generated-but-orphaned.
The new test passes for path load (baseline) and fails for file:// URL load,
demonstrating the bug in the parser's own harness. Related: swagger-api#2201, swagger-api#1166.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What / why
Adds a failing regression test for #1922 in the parser's own harness.
For an OAS 3.1 document that contains only internal (
#/components/...) references, parsing withresolve=trueandresolveFully=falseshould leave those$refs intact. Today the result depends on how the root document was loaded:FeeListResponse.fees.items.$ref#/components/schemas/FeeValues(preserved ✅)file://URLnull— schema inlined,$reflost ❌reproduce(also dependency-free, runnable against anyopenapi-generator-clijar which bundles this parser):This is OAS 3.1-only (the equivalent 3.0 spec preserves the
$refunder both path and URL load) and reproduces on every release from 2.1.22 through 2.1.43 (latest).Test results (this PR)
The two failing assertions are the bug. Draft because the test is intended to fail until the parser is fixed.
Why it matters downstream
openapi-generator'sCodegenConfiguratorcallsreadLocation(...)withresolve=true, resolveFully=falseand relies on internal$refs being preserved (it runs its ownInlineModelResolver). Callers that pass the spec as a URL — the Maven/Gradle plugins, andquarkus-openapi-generator(configurator.setInputSpec(specFilePath.toUri().toString())) — get the refs back inlined, so every reused component is duplicated per use-site (<Parent><Prop>Inner,<Parent><Prop>for nullableanyOf,<Operation>Requestfor request bodies) and the canonical component is emitted but orphaned.Root-cause localization (for a fix)
For OAS 3.1,
OpenAPIV3Parser.resolve(...)runs the dereferencer wheneverisResolve() || isResolveFully(). InOpenAPIDereferencer31.dereference(...)the root document is registered in the in-memory reference set as"local"only whenrootUriis blank; with a non-blankfile://rootUriit is not, so inReferenceVisitor.resolveSchemaRef(...)an internal#/...pointer is resolved against thefile://base URI and the document is re-read/dereferenced (inlined). A fix likely lives here: internal (ReferenceUtils.isLocalRef) pointers into the root document should be handled consistently regardless of whether the root was loaded by path or byfile://URL (i.e. not inlined underresolveFully=false). Related: #2201, #1166.I'm happy to iterate on the actual fix with maintainer guidance on the intended
resolvevsresolveFullycontract for internal refs.🤖 Generated with Claude Code