protobuf: reflect/protoregistry: conflicts with same filename
Hello,
Sharing a same .proto filename with different proto package names results in these errors:
2020/05/10 15:03:12 WARNING: proto: file "common.proto" is already registered previously from: "git.example.com/proto/common" currently from: "git.example.com/proto/a" A future release will panic on registration conflicts. See: https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict
2020/05/10 15:03:12 WARNING: proto: file "common.proto" is already registered previously from: "git.example.com/proto/common" currently from: "git.example.com/proto/b" A future release will panic on registration conflicts. See: https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict
Here is my layout:
proto/
common/
common.proto (package common)
a/
common.proto (package a and importing common/common.proto)
foo.proto (importing common.proto)
...
b/
common.proto (package b and importing common/common.proto)
bar.proto (importing common.proto)
...
I don’t think my case is similar to both quoted in documentation https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict. I don’t generate multiple times a same proto file (here I generate one time common/common.proto and I import from others files) and I’m using different package names. It would be better if I rename package common to something else, but I don’t think it’s my issue here.
What’s the best practice to solve this issue ? Is it normal to get this warning in my case ? I mean, it doesn’t look uncommon to have the same filename in different projects.
Thanks
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 36
- Comments: 54 (13 by maintainers)
Links to this issue
Commits related to this issue
- rename api.proto files to avoid namespace collision warning It seems like a proto library problem that we were getting these warnings, but we were. See https://github.com/golang/protobuf/issues/1122... — committed to bretmckee/microservice by bretmckee 3 years ago
- reflect/protoregistry: restore conflicting file names check There are inconsistencies between implementations on what happens when a single program contains generated code for multiple files with the... — committed to protocolbuffers/protobuf-go by neild 3 years ago
- rename api.proto files to avoid namespace collision warning It seems like a proto library problem that we were getting these warnings, but we were. See https://github.com/golang/protobuf/issues/1122... — committed to bretmckee/microservice by bretmckee 3 years ago
Sure, but that doesn’t seem to be problem in this issue though.
In my opinion, the protobuf developer site is lacking guidance in general in this area, and the
protoctool itself is not particularly friendly towards users who do not work in a mono-repo like Google does (where every.protosource file is relative to the root of the mono-repo). The open-source world is fundamentally a collection of disjoint repositories. There needs to be better guidance on what is the appropriate import path for a.protofile and how to reference a.protofile that crosses repo boundaries.finally, I got the conflict panic! And l’d like to paste some doc from protobuf here: doc from panic
as the doc states: The protobuf language assumes that all declarations are universally unique. note: all declarations not file names. Please consider fix it.
So we have the situation @dsnet describes. We have Go program that depends on two external libraries both of which have a
spec.protoand we get this warning when the program runsI agree with @strowk, at the very least there should be some second level logic based on package name to disambiguate source file name collisions. The workaround of changing how the protobuf is compiled does not work when an external library is managing how the protobuf is compiled.
Along the current logical arc, the implication is that all protobufs in all repositories globally, need to have unique filenames - which is not reasonable. I really hope the threat of
panicin future releases does not come to fruition.I also had similar problem and what I don’t understand is how it does not take “package” into account. In my case I have two events.proto files in two different folders, they generate events.pb.go , also in two different folders AND both of them have different “package” and go_package. Why do I get
proto: file "events.proto" is already registered? Is this a bug in protobuf or I don’t understand that documentation - https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict ? Particulary thatsounds like I should not have this problem, yet warning is printed
I think we should drop the requirement that the paths of registered files be unique.
The paths of source files are only weakly part of the protobuf data model at best. Unlike descriptor names, source file names are not used in any of the serialization forms. It is also expected that renaming files or moving descriptors between files have no user-visible effects.
In an environment where all the generated code is built at the same time, enforcing a requirement that source
.protofiles have unique names is easy. However, the nature of the Go build system is such that.pb.gofiles are usually generated in many different places at different times by different people and committed to source control. In this environment, enforcing uniqueness of source file paths is difficult.If we relax this requirement, we need to define what
Files.FindFileByPathreturns when multiple files match the requested path. I think the simplest answer is for it to return an error.Has the protobuf team made any further decisions on this issue?
Much like @rcgoodfellow, I have a Go program that depends on two third-party libraries, each of which defines a
telemetry.protofile at the top level of their project. With current google.golang.org/protobuf, the program panics unless I set the GOLANG_PROTOBUF_REGISTRATION_CONFLICT environment variable.This can’t be that uncommon a situation. At this point, I’m not really clear how the protobuf team expect the file-by-path registry to work outside of a monorepo setting.
We’re coming up this issues’ first birthday 🍰 Any resolution in sight?
@dsnet @neild It seems that the latest release went ahead and added enforcement as the default behavior. This of course broke code and we will have to go back and mitigate via env flags or build flags.
There could be a million reasons Go team has decided to do this, so this isn’t a criticism and like everything else, people aren’t going to be happy with the decision. I’m hoping you could address this issue here to let us know that this is just the way it is and close the issue or that there is some other way you plan to fix this in the future (by adding enforcement, this seems like the issue really should just be closed).
I would just like to move this issue towards resolution so we are all on the same page.
For anyone reading, your mitigations are:
go build -ldflags “-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn”
Env var: GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./main
This is really becoming an issue. I also don’t get why would it look/care for the proto filename. I’m using different package names for the protobuf and still have the issue complaining about proto file being registered twice.
My protos structure: service-a/entities.proto service-b/entities.proto
different
option go_package = "something";in both of them. If I include both packages I get:panic: proto: file "entities.proto" is already registeredI know I can solve this with absolute paths but it’s definitely not ideal.
We worked around it by using the organization/company/project name in the filenames (🤮), i.e.
orgname_common.proto.For those who just want to get around and not willing to change the build settings, you can have a check at this small CLI tool: https://github.com/tuimeo/go-proto-filename-prefixer
It modify the generated pb.go files and add prefix to the embedded filename.
This remains just as bizarre and unreasonable today as it was two years ago.
@neild
but why i have two protof iles like a/b.proto, c/b.proto , it goes panic? It’s obviously in a differante hierarchy
See @dsnet’s comment here: https://github.com/golang/protobuf/issues/1122#issuecomment-852577631
It’s a bug for a program to include two
.protofiles with the same name. This decision is made at the protobuf project level, and the maintainers of the Go implementation do not have the ability to change it. Sorry.I believe the recommendation is that any shared
.protofiles be given a name that ensures they have a unique prefix; for example,google/protobuf/any.protohas a prefix indicating the organization (google) and project (protobuf) that owns the file.Hi, since the issue was closed by https://github.com/protocolbuffers/protobuf-go/commit/febffdd88e85cb4402205142aaa1a4cc64d0d375, but then it was rollbacked at https://github.com/protocolbuffers/protobuf-go/commit/21e33cc91079beb975323466e237f2486ea29c10, shouldn’t it be reopened for visibility?
Modifying the
rawDesclike the proposed tool does is highly inappropriate. This issue is far more complex than presented.It would be nice to at least know how to generate files with
protocto avoid this, I can’t find any docs on thisLike I have no idea how the path ends up in the generated binary blob
Different
package YYYYandoption go_package = XXXin multiple.protoon my end… but same as above:I don’t understand why the file name is a problem if content is scoped to a package…
Does any of you have a reasonable solution? Should I modify all files (but it’s not a proper solution), or cross fingers so their panic warnings will never be implemented?
Thank you,
Agree with previous comments. Not everyone uses a monorepo, and enforcing unique file path across different services is unnecessary and troublesome.