Skip to content

fix(v3): update discriminator mapping of a nested oneOf after external ref resolution - #2407

Open
wyhasany wants to merge 1 commit into
swagger-api:masterfrom
wyhasany:bug/2406-nested-discriminator-mapping-null-key
Open

wyhasany wants to merge 1 commit into
swagger-api:masterfrom
wyhasany:bug/2406-nested-discriminator-mapping-null-key

Conversation

@wyhasany

Copy link
Copy Markdown

Pull Request

Description

ExternalRefProcessor.processSchema updates the discriminator.mapping of a composed schema that is nested in another schema (array items, properties, additionalProperties) after the external $refs of its oneOf/anyOf members have been rewritten. Since #2249 the lookup map is keyed by discriminator value, but it is queried with the member's original $ref, so refMap.get(...) is always null and mapping.put(null, newRef) is executed for every rewritten member. The result is a null key in the mapping and mapping values that are never updated (see #2406 for a reproducer and the history: #2087 introduced the block with the map inverted, which worked but threw Duplicate key when several values map to the same schema, #2222).

This change indexes the mapping in ExternalRefProcessor as ref -> list of discriminator values, so that

SchemaProcessor.changeDiscriminatorMapping, which later rewrites the root-relative paths produced by the first pass to #/components/schemas/..., only updated the first mapping entry pointing at the resolved ref; it now updates all of them, otherwise the second value mapping to the same schema stayed unresolved.

Behaviour for local #/components/schemas/... refs is unchanged (they are not rewritten and never enter either loop).

Fixes: #2406

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • ♻️ Refactor (non-breaking change)
  • 🧪 Tests
  • 📝 Documentation
  • 🧹 Chore (build or tooling)

Checklist

  • I have added/updated tests as needed
  • I have added/updated documentation where applicable
  • The PR title is descriptive
  • The code builds and passes tests locally
  • I have linked related issues (if any)

Screenshots / Additional Context

Issue2406Test uses external file refs in a oneOf nested in array items, with two discriminator values mapping to the same schema. On master it fails (Unable to load RELATIVE ref: ./TypeA.yaml is reported, the mapping keeps a -> ./TypeA.yaml etc. and gets a null key):

message: Unable to load RELATIVE ref: ./TypeA.yaml path: .../issue-2406
mapping: a -> ./TypeA.yaml
mapping: b -> ./TypeB.yaml
mapping: bLegacy -> ./TypeB.yaml
mapping: null -> ./schemas/TypeB.yaml

With this change the resolved document has no messages and:

mapping: a -> #/components/schemas/TypeA
mapping: b -> #/components/schemas/TypeB
mapping: bLegacy -> #/components/schemas/TypeB

Issue2222Test (local refs) and OpenAPIV3RefTest#testDiscriminatorMappingRefsUpdated still pass.

…l ref resolution

ExternalRefProcessor.processSchema queried a map keyed by discriminator value
with the member's original $ref, so the lookup always returned null: a null key
was put into the mapping and the real entries were left unresolved (regression
introduced while fixing swagger-api#2222). Index the mapping by ref -> discriminator
values instead, so that several values can map to the same schema and the
lookup by the original $ref works again.

SchemaProcessor.changeDiscriminatorMapping rewrote only the first mapping entry
pointing at a resolved ref; rewrite all of them.

Add Issue2406Test with external file refs in a oneOf nested in array items and
two discriminator values mapping to the same schema.
@wyhasany wyhasany closed this Oct 13, 2026
@wyhasany wyhasany reopened this Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant