Skip to content

Fix nested allOf/anyOf merging#2471

Merged
mromaszewicz merged 1 commit into
oapi-codegen:mainfrom
mromaszewicz:fix/issue-1905
Jul 16, 2026
Merged

Fix nested allOf/anyOf merging#2471
mromaszewicz merged 1 commit into
oapi-codegen:mainfrom
mromaszewicz:fix/issue-1905

Conversation

@mromaszewicz

Copy link
Copy Markdown
Member

Closes: #1905

In mergeOpenapiSchemas, result.OneOf was assigned from s1.OneOf and s2.OneOf before the transitive AllOf flattening loop, which then overwrote s1 and s2 entirely. Any OneOf (or AnyOf) that surfaced from a nested allOf member was silently dropped, causing the union field and variant types to disappear from the generated output.

Fix: capture top-level OneOf/AnyOf first, then accumulate whatever bubbles up from each allOf merge before assigning to result. AnyOf had the same ordering bug (no result.AnyOf assignment at all), fixed in the same pass.

Adds a reproduction schema (NestedOneOfInAllOf) and TestIssue1905 to the aggregates/allof test fixture to lock in the correct generated output.

Closes: oapi-codegen#1905

In `mergeOpenapiSchemas`, `result.OneOf` was assigned from `s1.OneOf` and
`s2.OneOf` before the transitive AllOf flattening loop, which then overwrote
`s1` and `s2` entirely. Any `OneOf` (or `AnyOf`) that surfaced from a nested
allOf member was silently dropped, causing the union field and variant types
to disappear from the generated output.

Fix: capture top-level OneOf/AnyOf first, then accumulate whatever bubbles up
from each allOf merge before assigning to result. AnyOf had the same ordering
bug (no `result.AnyOf` assignment at all), fixed in the same pass.

Adds a reproduction schema (`NestedOneOfInAllOf`) and `TestIssue1905` to the
`aggregates/allof` test fixture to lock in the correct generated output.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@mromaszewicz
mromaszewicz requested a review from a team as a code owner July 16, 2026 16:25
@mromaszewicz mromaszewicz added the bug Something isn't working label Jul 16, 2026
@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes two silent-drop bugs in mergeOpenapiSchemas: result.OneOf was assigned from the raw s1/s2 fields before the transitive allOf flattening loop could surface nested OneOf members, and result.AnyOf had no assignment at all, causing top-level AnyOf to be dropped entirely. The fix captures top-level values first, accumulates whatever mergeAllOf bubbles up from nested members, then writes once to result.

  • pkg/codegen/merge_schemas.go: introduce oneOf/anyOf accumulators that are built in two passes — before and after the transitive flattening — then assigned to result at the end.
  • internal/test/aggregates/allof/spec.yaml + allof_test.go + allof.gen.go: add the NestedOneOfInAllOf reproduction schema and TestIssue1905 regression test to the existing aggregates/allof leaf, following project placement conventions.

Confidence Score: 5/5

Safe to merge — the change is a focused, correct fix in the schema-merge walk with a generated-output regression test locking in the expected result.

The logic change is minimal and clearly correct: two accumulator variables replace an early assignment that lost data, and the missing result.AnyOf assignment is added. The generated fixture is proportional to the schema change, no unrelated churn, and test placement follows project conventions. No breaking changes beyond the expected improvement in generated output for schemas that previously hit the bug.

No files require special attention.

Important Files Changed

Filename Overview
pkg/codegen/merge_schemas.go Correctly fixes two related bugs: (1) OneOf from nested allOf members was silently dropped because result.OneOf was assigned before the transitive allOf flattening; (2) result.AnyOf was never assigned at all, causing top-level AnyOf to also be dropped. Fix captures top-level values first, accumulates bubbled-up values from each mergeAllOf call, then assigns once at the end.
internal/test/aggregates/allof/allof_test.go Adds TestIssue1905 regression test that uses reflection to verify the union field is present and the two variant types are generated; follows the existing naming convention in this file.
internal/test/aggregates/allof/allof.gen.go Generated output correctly reflects the new NestedOneOfInAllOf schema: struct with flat AFoo field plus union json.RawMessage, two variant types, and the full set of As/From/Merge/Marshal/Unmarshal helpers. New runtime import is appropriate. Diff is proportional to the schema change with no unrelated churn.
internal/test/aggregates/allof/spec.yaml Adds NestedOneOfInAllOf schema to the existing aggregates/allof leaf — correct placement per project conventions. Provenance comment follows the established format used by other entries in the file.

Reviews (1): Last reviewed commit: "Fix nested allOf/anyOf merging" | Re-trigger Greptile

@mromaszewicz
mromaszewicz merged commit 823a7a7 into oapi-codegen:main Jul 16, 2026
15 checks passed
@mromaszewicz
mromaszewicz deleted the fix/issue-1905 branch July 16, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deeply nested oneOf gets lost when merging allOf

1 participant