Summary
protoc-gen-openapiv3 names its per-service output file from the service name only, unqualified by proto package. Two services with the same name in different packages therefore map to the same filename, and one spec is silently dropped — the affected service ends up with no OpenAPI documentation at all.
Reproduction
Two services sharing a name in different packages:
// anghamna/b2b/v1/service.proto
package anghamna.b2b.v1;
service VideoStreamingService {
option (sebuf.http.service_config) = { base_path: "/api/b2b/v1" };
rpc GetLiveChannelsWithStreams(...) returns (...) {
option (sebuf.http.config) = { path: "/get-live-channels-with-streams" };
}
}
// anghamna/videostreaming/v1/service.proto
package anghamna.videostreaming.v1;
service VideoStreamingService {
option (sebuf.http.service_config) = { base_path: "/api/video-streaming/v1" };
rpc GetLiveStreams(...) returns (...) { option (sebuf.http.config) = { path: "/get-live-streams" }; }
rpc GetVodStreams(...) returns (...) { option (sebuf.http.config) = { path: "/get-vod-streams" }; }
}
Both resolve to VideoStreamingService.openapi.yaml.
Observed
buf generate warns and continues:
duplicate generated file name "VideoStreamingService.openapi.yaml". Generation will
continue without error here and drop the second occurrence of this file, but please
raise an issue with the maintainer of the plugin.
In a real repo with 15 services this produced 14 spec files. The surviving VideoStreamingService.openapi.yaml contained only the b2b paths (/api/b2b/v1/get-live-channels-with-streams); anghamna.videostreaming.v1.VideoStreamingService and its two RPCs were absent from the generated docs entirely.
Which service wins depends on generation order, so this can also flip silently between runs or protoc versions.
Expected
Either:
- Qualify the filename when a collision would occur (or always), e.g.
anghamna.b2b.v1.VideoStreamingService.openapi.yaml / a package-derived path — so both specs are emitted; or
- Fail loudly at generation time with a clear message naming both services, matching how the toolkit already fails loud on other unrepresentable inputs (
ValidateFileURLParams, CheckESMessageAnnotations, checkNoEnumParamsES).
Silently emitting an incomplete spec set is the worst of the three outcomes — consumers get a spec that looks complete.
Note
Bundle mode already handles the analogous collision for schemas by proto-package-qualifying names (sebuf.test.User → sebuf_test_User, per the "OpenAPI Bundle Mode" docs). The gap is only in per-service file naming.
Environment
Verified on main @ d3bcc2a (latest at time of writing) — 15 services in the
protos, 14 spec files emitted, same duplicate generated file name warning, and the
surviving VideoStreamingService.openapi.yaml contains only the b2b paths.
- sebuf
main @ d3bcc2a
- buf 1.57.2
It also reproduces on the older v0.17.0 pin, which is only meant to say the bug is
long-standing rather than a recent regression — the report itself is against main.
Summary
protoc-gen-openapiv3names its per-service output file from the service name only, unqualified by proto package. Two services with the same name in different packages therefore map to the same filename, and one spec is silently dropped — the affected service ends up with no OpenAPI documentation at all.Reproduction
Two services sharing a name in different packages:
Both resolve to
VideoStreamingService.openapi.yaml.Observed
buf generatewarns and continues:In a real repo with 15 services this produced 14 spec files. The surviving
VideoStreamingService.openapi.yamlcontained only theb2bpaths (/api/b2b/v1/get-live-channels-with-streams);anghamna.videostreaming.v1.VideoStreamingServiceand its two RPCs were absent from the generated docs entirely.Which service wins depends on generation order, so this can also flip silently between runs or protoc versions.
Expected
Either:
anghamna.b2b.v1.VideoStreamingService.openapi.yaml/ a package-derived path — so both specs are emitted; orValidateFileURLParams,CheckESMessageAnnotations,checkNoEnumParamsES).Silently emitting an incomplete spec set is the worst of the three outcomes — consumers get a spec that looks complete.
Note
Bundle mode already handles the analogous collision for schemas by proto-package-qualifying names (
sebuf.test.User→sebuf_test_User, per the "OpenAPI Bundle Mode" docs). The gap is only in per-service file naming.Environment
Verified on
main@d3bcc2a(latest at time of writing) — 15 services in theprotos, 14 spec files emitted, same
duplicate generated file namewarning, and thesurviving
VideoStreamingService.openapi.yamlcontains only theb2bpaths.main@d3bcc2aIt also reproduces on the older
v0.17.0pin, which is only meant to say the bug islong-standing rather than a recent regression — the report itself is against
main.