Skip to content

[BUG] fix(InlineModelResolver): do not merge distinct inline enums sharing the same values (#23978)#24009

Open
seonwooj0810 wants to merge 2 commits into
OpenAPITools:masterfrom
seonwooj0810:fix/issue-23978-inline-enum-structural-merge
Open

[BUG] fix(InlineModelResolver): do not merge distinct inline enums sharing the same values (#23978)#24009
seonwooj0810 wants to merge 2 commits into
OpenAPITools:masterfrom
seonwooj0810:fix/issue-23978-inline-enum-structural-merge

Conversation

@seonwooj0810

@seonwooj0810 seonwooj0810 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #23978

Problem

Since 7.23.0, inline enums that share the same values but are defined on different properties are no longer generated as separate types — only the first enum gets its own schema and the second property silently reuses it. This worked correctly in 7.22.0. The reporter bisected the change to #23856 (commit 170778a), and a second user confirmed the same behaviour on kotlin-spring.

Root cause

#23856 added a structural-signature fallback to matchGenerated(). To dedup the same multi-file $ref object schema across passes (where the Swagger Parser mutates shared Schema objects), the structural mapper strips description, type and example before comparing.

For object schemas that is fine, but for enum schemas it is too aggressive: two enums that list the same values but represent different things are distinguished only by their description. Stripping it makes their structural signatures identical, so the second enum matches the first and reuses its $ref.

Fix

Skip the structural-signature fallback for enum schemas in matchGenerated() — enums deduplicate on exact content only (the 7.22.0 behaviour). Object-schema multi-file deduplication is unchanged.

The diff is small and localized to matchGenerated() plus a new isEnumSchema() helper.

Test evidence

Added InlineModelResolverTest#doNotMergeDistinctInlineEnumsSharingTheSameValues, which builds an object with two inline enum properties that share the same values but carry different descriptions and asserts each is promoted to its own schema. The test fails on master (the two $refs are equal) and passes with this fix.

Full InlineModelResolverTest run: 56 tests, 0 failures — including the existing structural/multi-file dedup regression tests added by #23856 (resolveInlineModelDeduplicatesWhenParserMutatesPropertyTypes, the root.yaml dedup tests), confirming the multi-file object dedup behaviour is preserved.

mvn -pl modules/openapi-generator test -Dtest=InlineModelResolverTest
Tests run: 56, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS

Verification done: (1) no in-flight PR (searched open PRs for 23978 / InlineModelResolver enum); (2) issue unassigned, no claim comments; (3) code-focused (.java only); (4) reproduced on latest upstream/master with a failing unit test; (5) maintainer (@wing328) acknowledged the regression and cc'd the author of the change.


Summary by cubic

Fixes a regression that merged distinct inline enums with the same values; each inline enum now generates its own schema. Regenerates samples so header/query string enums use the new testEnumParameters_enum_header_string_parameter type.

  • Bug Fixes
    • In InlineModelResolver.matchGenerated(), skip structural-signature fallback for enum schemas; object-schema multi-file dedup stays the same.
    • Add isEnumSchema() helper and unit test doNotMergeDistinctInlineEnumsSharingTheSameValues.
    • Regenerate samples (C# generichost, PHP Laravel, Rust server incl. deprecated): add TestEnumParametersEnumHeaderStringParameter, update refs/converters, and align API signatures and tests (incl. FakeApiTests) to the new enum type.

Written for commit 86f45b3. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

@seonwooj0810 seonwooj0810 force-pushed the fix/issue-23978-inline-enum-structural-merge branch 3 times, most recently from 5663d49 to e87bb24 Compare June 23, 2026 08:54
@seonwooj0810

Copy link
Copy Markdown
Contributor Author

Rebased onto latest master and regenerated the affected samples (sequentially, to avoid the parallel-generation nondeterminism in generate-samples.sh). The core change is covered by InlineModelResolverTest.

The remaining red checks are generated-sample builds (.NET/PHP/Python) plus the csharp generichost .openapi-generator/FILES, which shows non-deterministic entries across generation runs (e.g. a test file alternately listed/omitted). Could a maintainer advise whether these are pre-existing sample-harness flakes vs. something this change should address?

@seonwooj0810

Copy link
Copy Markdown
Contributor Author

Correction to my earlier comment — on closer inspection this is the same situation as #24007, so my "unrelated / nondeterminism" note doesn't hold. Breakdown:

Build .Net* (samples/client/petstore/csharp/generichost/.../FormModels) — caused by this PR, not fixable by regeneration.
Now that the same-valued sibling inline enums are no longer merged, the generated API (FakeApi.cs) types enum_header_string / enum_query_string as TestEnumParametersEnumHeaderStringParameter, while the generated test (FakeApiTests.cs) still declares them as TestEnumParametersRequestEnumFormString → CS1503 on arguments 3 and 7. Regenerating on this branch reproduces it, so it's a csharp generichost test-generation gap this PR is the first to expose, not a stale sample. Filed separately as #24112.

Build PHP (.../php-laravel/) — unrelated composer "requirements could not be resolved" dependency/infra failure.

Samples up-to-date — the .openapi-generator/FILES for the csharp generichost FormModels samples need regenerating; I'll push that.

As with #24007, the .NET breakage is generator-side and beyond the scope of this inline-resolver fix, so I'd appreciate maintainer guidance on the preferred direction.

…the same values

The structural-signature fallback added in OpenAPITools#23856 strips 'description',
'type' and 'example' before comparing schemas so that multi-file $ref
object schemas mutated by the parser still deduplicate. For enum schemas
this is too aggressive: two enums that list the same values but mean
different things are distinguished only by their description, so stripping
it wrongly unifies them and the second usage silently reuses the first
enum's type (regression in 7.23.0, worked in 7.22.0).

Skip the structural fallback for enum schemas in matchGenerated() so enums
deduplicate on exact content only. Object-schema multi-file dedup is
unaffected.

Fixes OpenAPITools#23978
@seonwooj0810 seonwooj0810 force-pushed the fix/issue-23978-inline-enum-structural-merge branch from e87bb24 to 841c1ca Compare June 24, 2026 01:54
Align the FakeApiTests enumHeaderString/enumQueryString parameter types
with the FakeApi signature (EnumHeaderStringParameter) so the samples
match CI-generated output and compile.

Signed-off-by: seonwooj0810 <seonwooj0810@gmail.com>
@seonwooj0810 seonwooj0810 force-pushed the fix/issue-23978-inline-enum-structural-merge branch from 841c1ca to 86f45b3 Compare June 24, 2026 03:21
@seonwooj0810

Copy link
Copy Markdown
Contributor Author

Update + correction to my earlier comment — I was wrong about the .NET failures, and I've now pushed a fix that greens them.

Build .Net* (...generichost/.../FormModels) — fixed (now green).
My earlier "not fixable by regeneration" was incorrect. The committed FakeApiTests.cs typed enumHeaderString/enumQueryString as TestEnumParametersRequestEnumFormString, inconsistent with the FakeApi signature (...EnumHeaderStringParameter) → CS1503. The key finding is that this output is environment-dependent, not nondeterministic: on my machine (macOS) regeneration stably produces the inconsistent test types — sequential and batch alike — whereas CI generates the self-consistent EnumHeaderStringParameter for both the API and the test. I have not isolated the exact variable: it is not the JDK (11 and 25 behave identically here), not the locale, and a Docker/Linux check was inconclusive (Docker Desktop mounts the host macOS filesystem). I committed the CI-consistent samples, which greens both Samples up-to-date and the .NET builds.

Clue for whoever digs deeper: within a single generation run, FakeApi.cs and FakeApiTests.cs disagree on the same parameter's model type, and FakeApi.cs is stable across environments — so the divergence is specific to the api_test generation path, not global model naming. (Filed/reframing as #24112; the templates themselves are fine — CI proves they emit the correct output.)

Attribution: this is PR-caused in that the split exposes the order/environment-dependent naming (master has no split, so it compiles everywhere) — but not "parallel-generation nondeterminism."

Build PHP (.../php-laravel/) — failing but unrelated to this PR: composer refuses laravel/framework ^10.0 because those versions are now flagged by packagist security advisories (PKSA-*). The php-laravel sample isn't touched by this change, so this is a repo-wide issue (not fixable from this PR) rather than anything it introduced. Aside from that, this PR's checks are green.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] [Engine?] InlineModelResolver merges different inline enums that have the same values

1 participant