Skip to content

fix(gen): preserve schema Ref in single-element allOf fast path#1652

Merged
ernado merged 2 commits intoogen-go:mainfrom
michaelbeutler:fix/allof-single-element-ref-loss
Mar 26, 2026
Merged

fix(gen): preserve schema Ref in single-element allOf fast path#1652
ernado merged 2 commits intoogen-go:mainfrom
michaelbeutler:fix/allof-single-element-ref-loss

Conversation

@michaelbeutler
Copy link
Copy Markdown
Contributor

When a component schema uses allOf with a single element (e.g., nullable: true + type: object + allOf: [single item]), the allOf() fast path in gen/schema_gen_sum.go returned the inner schema directly, losing the outer schema's Ref field. This caused the type to be registered as anonymous instead of ref-keyed, leading to anonymous type name conflict errors when the same schema was referenced across multiple operations.

The multi-element allOf path already preserves Ref via mergedSchema.Ref = schema.Ref, but the single-element fast path skipped this.

Fixes #1651

Likely fixed by PR:

  • #1448 — anonymous type name conflict: "OptSecretConfig" at tstorage.merge — exact same error path and root cause (single-element allOf losing Ref)
  • #1488 — OptError not generated for recursive schema with single-element allOf: [$ref] + nullable: true — this is the same single-element allOf fast path bug; the inner schema loses Ref identity

Fix

Copy the outer schema's Ref onto the inner schema (via shallow copy) before generating, so the type is registered under the correct reference key and reused by subsequent operations.

Reproduction

A schema like:

Bar:
  nullable: true
  type: object
  allOf:
    - type: object
      properties:
        value:
          type: number

referenced from a parent schema used in two operations, once directly, once inside another allOf merge, would fail with: anonymous type name conflict: "Bar"

Test plan

  • Added positive test case to _testdata/positive/allOf.yml reproducing the collision pattern
  • Added integration test in internal/integration/all_of_test.go (getFoo / getAdminFoo)
  • go test . -run TestGenerate/Positive/allOf passes
  • go test ./internal/integration -run TestAllof passes
  • go test ./gen/... — all existing tests pass
  • go test . -run TestGenerate — all positive/negative/example specs pass

When a component schema uses allOf with a single element, the allOf()
fast path returned the inner schema directly without copying the outer
schema's Ref field. This caused the type to be registered as anonymous
instead of ref-keyed, leading to "anonymous type name conflict" errors
when the same schema was referenced from multiple operations.

Fixes ogen-go#1651
@ernado ernado merged commit 4787d6b into ogen-go:main Mar 26, 2026
15 checks passed
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.

allOf: anonymous type name conflict when $ref'd schema has single-element allOf

2 participants