fix codegen for same type used with multiple discriminators #2108
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.
Fix Missing Discriminator Mappings When Multiple Values Map to Same Schema
Problem
When an OpenAPI spec has multiple discriminator values that map to the same schema type, the code generator would only include one of the values in the generated code, and which value was included would vary randomly between runs.
Example
Given an OpenAPI spec with discriminator mappings like:
The generated
ValueByDiscriminator()switch would be incomplete, randomly including eithertype_aORtype_b, but not both:This means valid discriminator values specified in the OpenAPI spec would fail at runtime with "unknown discriminator value" errors.
Root Cause
The discriminator mapping builder in
generateUnion()iterated over the spec's discriminator map and broke after finding the first match:Since Go map iteration order is randomized, this meant:
type_awas processed first and included (makingtype_bfail at runtime)type_bwas processed first and included (makingtype_afail at runtime)Solution
1. Include All Discriminator Mappings
Updated
generateUnion()in schema.go to:breakthat caused mappings to be silently droppedBefore:
After:
2. Added
SortedMappingKeys()Helper MethodAdded a helper method to the
Discriminatorstruct that returns mapping keys in sorted order, ensuring deterministic code generation across runs:3. Updated Templates
Modified union.tmpl to use sorted keys:
SortedMappingKeys()instead of direct map iteration for deterministic output$matchedflag inFrom*andMerge*methods to use the first (alphabetically) discriminator valueValueByDiscriminator()includes ALL discriminator values as switch cases{{$matched := false -}} {{range $value := $discriminator.SortedMappingKeys -}} {{$type := index $discriminator.Mapping $value -}} {{if and (eq $type $element) (not $matched) -}} v.{{$discriminator.PropertyName}} = "{{$value}}" {{$matched = true -}} {{end -}} {{end -}}4. Improved Validation
Updated validation logic to check that all union elements have at least one discriminator mapping, rather than requiring count equality between mappings and elements (which incorrectly fails when multiple discriminator values map to the same schema).
Changes Summary
Modified Files
pkg/codegen/schema.go:SortedMappingKeys()method toDiscriminatorstructgenerateUnion()to sort keys and include all mappingspkg/codegen/templates/union.tmpl:From{{ .Method }}to use sorted keys with early-exitMerge{{ .Method }}to use sorted keys with early-exitValueByDiscriminator()to use sorted keysTest Coverage
Impact
Generated Code Changes
For schemas with multiple discriminator values mapping to the same type:
ValueByDiscriminator()switch: Now includes ALL discriminator values as cases (previously missing random values)From*methods: Consistently use the first alphabetically sorted discriminator valueMerge*methods: Same deterministic behaviorExample:
Backward Compatibility
This is a bug fix that corrects missing discriminator mappings. For projects with multiple discriminator values mapping to the same schema:
Before this fix:
"unknown discriminator value: type_b"for valid discriminator valuesAfter this fix:
From*/Merge*methods is the alphabetically first valueThis change fixes a correctness bug where valid OpenAPI discriminator mappings were silently dropped, causing runtime failures.
Verification
TestOneOfWithDiscriminator_MultipleMappingsToSameSchemavalidates all discriminator values work