apache/beam · error
project cannot be empty, got
Error message
project cannot be empty, got %v
What it means
RequesterBillingProject configures the project billed for GCS requester-pays operations, and it rejects an empty project string. Since an empty billing project can never be valid for GCS API calls, the function fails fast with this error instead of deferring to a confusing GCS-side auth error.
Solutions
- Pass a valid non-empty GCP project ID.
- Guard before calling: check the value is non-empty and fail earlier with a clearer message.
- Fix the source (flag, env var, config key) that produced the empty string.
- Wire a sensible default project for the environment.
Example fix
// before
if err := gcs.RequesterBillingProject(project); err != nil { ... } // project == ""
// after
if project == "" {
return fmt.Errorf("billing project must be set via --gcs_billing_project")
}
if err := gcs.RequesterBillingProject(project); err != nil { ... } Defensive patterns
Strategy: validation
Validate before calling
if project == "" {
return errors.New("GCS billing project must be a non-empty GCP project ID")
}
return gcs.RequesterBillingProject(project) Try / catch
if err := gcs.RequesterBillingProject(project); err != nil {
if strings.Contains(err.Error(), "project cannot be empty") {
return fmt.Errorf("set --gcs_billing_project: %w", err)
}
return err
} Prevention
- Validate flags/env at startup before touching the Beam pipeline.
- Fail fast with actionable messages naming the missing config key.
- Set defaults per environment in config management.
- Never pass config strings unchecked into RequesterBillingProject.
When it happens
Trigger: Calling RequesterBillingProject("") — typically from an empty config value, unset flag, or an environment variable/env lookup that returned "".
Common situations: Flag/env not set in CI; config file key missing so the default empty string is passed; test code forgot to set the project.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- expected 1 option, got
- buffer_sec must be >= 0, got
- capacity of cache cannot be negative, got
- could not resolve to a temp directory for import batch files
- could not unmarshal iterable coder from
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/61dc55f053aa176a.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/io/filesystem/gcs/gcs.go:167
client, err = gcsx.NewUnauthenticatedClient(ctx)
if err != nil {
panic(errors.Wrapf(err, "failed to create GCS client"))
}
}
return &fs{
client: client,
}
}
func SetRequesterBillingProject(project string) {
billingProject = project
}
// RequesterBillingProject configure project to be used in google storage operations
// with requester pays actived. More informaiton about requester pays in https://cloud.google.com/storage/docs/requester-pays
func RequesterBillingProject(project string) error {
if project == "" {
return fmt.Errorf("project cannot be empty, got %v", project)
}
// The hook itself is defined in beam/core/runtime/harness/file_system_hooks.go
return hooks.EnableHook(projectBillingHook, project)
}
func (f *fs) Close() error {
return f.client.Close()
}
func (f *fs) List(ctx context.Context, glob string) ([]string, error) {
bucket, object, err := gcsx.ParseObject(glob)
if err != nil {
return nil, err
}
// Compile the glob pattern to a regex. We use a custom glob-to-regex
// translation that treats / as a regular character (not a separator),
// since GCS object names are flat. This also supports ** for recursiveView on GitHub (pinned to 12126d8942)