Skip to content

Buf CLI FAQs

Why can't buf generate find a file in my import statements?

Usually, this issue is because of a mismatch between the relative locations of the input to the buf generate command and the location specified in the import path. The buf generate command uses the location of your workspace's buf.yaml file as the root by default, so with this directory structure:

.
├── buf.gen.yaml
├── buf.yaml
└── proto
    ├── foo
    │   └── foo.proto
    └── bar
        └── bar.proto

If you run buf generate from the root, then your import paths should be an absolute path from that location. For example, if you wanted bar.proto to import foo.proto, the statement should be:

proto/bar/bar.proto
import "proto/foo/foo.proto";

However, if you specify an input to buf generate other than the module's root, the input will be prepended to the import path when looking for the file. For example, if you pass the proto directory as the input:

$ buf generate proto

then the Buf CLI looks for foo.proto at proto/proto/foo/foo.proto, which doesn't exist. You would need to change your import path to be:

proto/bar/bar.proto
import "foo/foo.proto";

My imports are working, but now I get "unknown type" errors when trying to use my imported type.

When importing from another package, you need to reference your types using the full package name. So, using the above directory structure, importing a Foo into your bar.proto file would look like this:

proto/bar/bar.proto
syntax = "proto3";

package proto.bar;

import "proto/foo/foo.proto";

message Bar {
  proto.foo.Foo myFoo = 1;  // Note the full package name
}

Is there an SDK to run Buf CLI commands in Go (or any other language)?

No, we don't have an SDK for the Buf CLI. If you want to use the Buf CLI as part of some automation, then you should shell out to it.

How do I check whether generated code is up-to-date?

Run buf generate and check for a diff in your VCS (either locally or as part of your CI workflow).

Does breaking change detection work on changes to custom options such as google.api.http?

No. The Google HTTP options are effectively custom options—they're from Google, but they're not part of Protobuf. Doing breaking change detection for options such as this can't happen easily inside of Buf, because there are an infinite number of these options and the semantics are different for each. So, we don't validate changes to custom options as part of breaking change detection.

Why am I seeing errors when trying to manage my Buf installation with tools.go?

This isn't an issue with Buf—all Go CLI tools can have this problem when using this approach. Despite its suggestion on the Go wiki, we consider it somewhat of an anti-pattern at Buf. We don't support or recommend using tools.go.

Programs are built (and tested) with a specific set of dependencies, and the tools.go method results in those dependencies being resolved with the dependencies of your own program (and other tools), which is ill-advised at best and incorrect at worst. Go packages are generally not supposed to change in incompatible ways while keeping the same identity (which is why v2 and v1 packages, for example, will have different import paths). Unfortunately, people break things and sometimes breaking changes are published on minor releases with the same import path. When this happens, the tools.go approach becomes problematic.

We recommend that you install Go tooling like anything else—either with individual go install calls or from released binaries. This way you are insulated from this problem. In addition, with Go v1.16, you can specify versions to go install, so ensuring everyone is using the same version for tooling is easily doable without using go.mod.

You can find Buf’s officially recommended command for installing from source using go install on the installation page. Using this command causes the Go tool to ignore go.mod, so the versions of Buf dependencies will be the exact ones that we intend.

Why do I see the error Failure: file "..." was generated multiple times: once by plugin "buf.build/protocolbuffers/csharp" and again by plugin "buf.build/protocolbuffers/csharp"?

C# plugins require you to set a base_namespace option in your buf.gen.yaml file to tell the plugin to generate files in a directory hierarchy matching the class namespace. A configuration similar to this should fix the issue:

version: v1
managed:
  enabled: true
plugins:
  - plugin: buf.build/protocolbuffers/csharp
    out: gen/proto/csharp
    opt: base_namespace=NAMESPACE

The PHP gRPC plugin isn't generating interfaces with buf but generates them with protoc.

How can I generate them with buf?

The php_generic_services file option must be set to generate interfaces, but Protobuf removed the option. It only works with older versions of protoc and doesn't work with buf.

Can I use different plugin options per module?

Yes. You can use multiple buf.gen.yaml files and specify different inputs and plugins per file. Use the --template flag with buf generate to select the template to generate with:

$ buf generate --template buf.foo.gen.yaml
$ buf generate --template buf.bar.gen.yaml

See the usage examples also.

Can I use a plugin that accesses the file system?

The plugin protocol defines how the compiler and a plugin interact with each other, and we can only support plugins that adhere to it. Plugins receive data via the CodeGeneratorRequest message, and output files via the CodeGeneratorResponse message. This allows us to implement generated SDKs and remote plugins, and to parallelize local code generation. You can use a plugin that accesses the file system, but it only works with local code generation, and you may have to work around other issues.

Why do I see a ModuleNotFoundError: No module named 'buf…' when trying to run my Python code?

This is a known issue with generating Python code. For a simple workaround, we recommend creating an __init__.py file in the root of your generated code.