Skip to content

protoc-gen-openapi: fix schema name collision for deeply nested messages#473

Open
DenKoren wants to merge 2 commits intogoogle:mainfrom
DenKoren:pr_for_upstream
Open

protoc-gen-openapi: fix schema name collision for deeply nested messages#473
DenKoren wants to merge 2 commits intogoogle:mainfrom
DenKoren:pr_for_upstream

Conversation

@DenKoren
Copy link
Copy Markdown

@DenKoren DenKoren commented Apr 1, 2026

Summary

getMessageName in cmd/protoc-gen-openapi/generator/reflector.go only walked one parent level when building OpenAPI schema names from nested protobuf messages. This caused schema name collisions for messages nested 3+ levels deep.

Example: Given these proto definitions in the same package:

message A {
  message Create {
    message Request { ... }
  }
}

message B {
  message Inner {
    message Create {
      message Request { ... }
    }
  }
}

The old code produced Create_Request for both, because it only prepended the immediate parent (Create). Only the first schema survived in the generated OpenAPI spec — the others silently reused its (structurally incorrect) definition.

Backward compatibility

For backward compatibility, no_recursive_schema_naming option is introduced. If you need old behaviour, set this option to the generator via --openapi_ipt="no_recursive_schema_naming=true".

Default behaviour changed as old behaviour produced a bug in generated openapi spec that was hard to notice.

Fix

Replace the single-parent if check with a for loop that walks the full message hierarchy:

  • A.Create.RequestA_Create_Request
  • B.Inner.Create.RequestB_Inner_Create_Request

Tests

  • Existing tests pass — fixtures use at most 1 level of nesting, which was already handled correctly by both old and new code
  • Verified against a real-world proto API with 3-4 levels of message nesting — all schemas are now correctly disambiguated with unique names

getMessageName only walked one parent level when building OpenAPI
schema names from nested proto messages. Messages nested 3+ levels
deep (e.g. OuterAPI.Inner.Create.Request) all collapsed to the
same schema key (Create_Request), causing silent data loss in the
generated OpenAPI spec — only the first message's schema survived.

Replace the single parent check with a loop that walks the full
message hierarchy, producing fully disambiguated names like
OuterAPI_Inner_Create_Request.
@DenKoren DenKoren requested a review from a team as a code owner April 1, 2026 13:01
Add a new option that restores the legacy single-parent naming
behavior for projects that depend on the old schema names.

When no_recursive_schema_naming=true, A.B.C.Request produces
C_Request (old behavior). When false (the default), it produces
A_B_C_Request (new behavior).
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.

1 participant