Skip to content

[Bug]: Regression: resolveFully fails when components key does not match external file basename #2399

Description

@jimshowalter

Description

swagger-parser 2.1.48 reports a false resolution error when parsing an OpenAPI 3.0 document with ParseOptions#setResolveFully(true) and setValidateExternalRefs(true).

The document externalizes a schema under a components key (Foo-status) that does not case-fold-match the external file basename (fooStatus.json). A nested model file references the declared key via #/components/schemas/Foo-status.

  • What we're parsing: OpenAPI 3.0.3 spec split across api.json + external JSON model files (common codegen layout).
  • Spec version: OpenAPI 3.0 (3.0.3 in repro).
  • Parser behavior: Returns a non-null OpenAPI, but adds an error message to SwaggerParseResult#getMessages(). Callers that treat any parser message as fatal (e.g. codegen validation) fail CI even though the model is structurally valid.

2.1.47 accepts the identical input with messageCount=0.

Affected Version

io.swagger.parser.v3:swagger-parser-v3 2.1.48

Earliest version the bug appears in (if known): 2.1.48 (2.1.47 passes with identical input)

Steps to Reproduce

  1. Use the attached swagger-parser-repro-2.1.48.zip (standalone Gradle project; generic demo names only).
  2. Run ./run-repro.sh (or gradle -q classes && java -cp "$(gradle -q printRuntimeClasspath)" demo.ParseDemo).
  3. Observe parser messages.

Minimal schema shape (same files in both zips):

schemas/api.json — registers external schema by display name:

"components": {
  "schemas": {
    "Foo-item": { "$ref": "./models/fooItem.json" },
    "Foo-status": { "$ref": "./models/common/fooStatus.json" }
  }
}

schemas/models/fooItem.json — nested ref to declared key:

"status": { "$ref": "../api.json#/components/schemas/Foo-status" }

schemas/models/common/fooStatus.json — simple string enum (ALPHA, BETA).

Java driver (ParseDemo.java):

ParseOptions options = new ParseOptions();
options.setResolveResponses(true);
options.setValidateExternalRefs(true);
options.setResolveFully(true);
SwaggerParseResult result =
    new OpenAPIV3Parser().readLocation(apiJson.getAbsolutePath(), null, options);

Compare with swagger-parser-repro-2.1.47.zip (only dependency version differs).

Expected Behavior

SwaggerParseResult#getMessages() is empty (as in 2.1.48's predecessor 2.1.47). Externalized schemas whose registered components key differs from the file basename (e.g. Foo-status + fooStatus.json) should resolve under full-resolve validation.

Actual Behavior

2.1.48 adds an error message:

Could not find components/schemas/fooStatus in contents of ./api.json

The registered key is Foo-status (lowercase foo-status). The parser appears to look up fooStatus from the file basename instead of the declared components key.

getOpenAPI() is non-null, but the error message breaks downstream tooling that fails on any parser message.

Logs / Stack Traces

2.1.47 (swagger-parser-repro-2.1.47.zip):

messageCount=0
RESULT: openAPI parsed
schema keys: [Foo-item, Foo-status, fooItem, fooStatus]

2.1.48 (swagger-parser-repro-2.1.48.zip):

messageCount=1
MESSAGE: Could not find components/schemas/fooStatus in contents of ./api.json
RESULT: openAPI parsed
schema keys: [Foo-item, Foo-status, fooItem, fooStatus, Foo-status_1]

Environment

  • Java version: OpenJDK 21 (repro also works on Java 17+)
  • Build tool: Gradle 9.7
  • OS: macOS (Darwin)

Additional Context

Attached zips (no vendor-specific identifiers):

  • swagger-parser-repro-2.1.47.zip — passing baseline
  • swagger-parser-repro-2.1.48.zip — failing repro

Regression introduced between 2.1.47 and 2.1.48 on the same unchanged OpenAPI input.

Checklist

  • I have searched the existing issues and this is not a duplicate.
  • I have provided sufficient information for maintainers to reproduce the issue.

Likely regression point (2.1.47 → 2.1.48)

Compared v2.1.47...v2.1.48 (12 commits). The failure matches external schema resolution changes in:

  1. Primary suspect: f605c3c — PR fix: External Refs with same name are ignored (#2055) #2382 (fixes External Refs with same name are ignored #2055), merged 2026-08-20
    • Rewrote ExternalRefProcessor and added ComponentNameAllocator
    • External schemas are allocated via allocateSchemaName() using computeDefinitionName($ref) (file basename, e.g. fooStatus) rather than the registered components key (Foo-status)
    • _N suffix collision behavior explains extra key Foo-status_1 in 2.1.48 output
  2. Possible contributor: 0255d18 — PR fix: Fix duplicate schemas from root document back-references (#1961) #2383 (fixes Duplicated schemas produced when shared schema references local schema #1961), merged 2026-08-25
    • Root-document back-reference handling in ResolverCache
    • Repro includes nested ../api.json#/components/schemas/Foo-status from an external model file
      v2.1.47 passes; v2.1.48 fails on identical input with:
      Could not find components/schemas/fooStatus in contents of ./api.json
      Compare: v2.1.47...v2.1.48

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions