{"record":{"id":"258eb950dbbc13c4","repo":"apache/beam","slug":"bucket-must-be-non-empty","errorCode":null,"errorMessage":"bucket must be non-empty","messagePattern":"bucket must be non-empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/util/gcsx/gcs.go","lineNumber":129,"sourceCode":"\t}\n\treturn w.Close()\n}\n\n// ReadObject reads the content of the given object in full.\nfunc ReadObject(ctx context.Context, client *storage.Client, bucket, object string) ([]byte, error) {\n\tr, err := client.Bucket(bucket).Object(object).NewReader(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn io.ReadAll(r)\n}\n\n// MakeObject creates a object location from bucket and path. For example,\n// MakeObject(\"foo\", \"bar/baz\") returns \"gs://foo/bar/baz\". The bucket\n// must be non-empty.\nfunc MakeObject(bucket, path string) string {\n\tif bucket == \"\" {\n\t\tpanic(\"bucket must be non-empty\")\n\t}\n\treturn fmt.Sprintf(\"gs://%v/%v\", bucket, path)\n}\n\n// ParseObject deconstructs a GCS object name into (bucket, name).\nfunc ParseObject(object string) (bucket, path string, err error) {\n\tparsed, err := url.Parse(object)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\tif parsed.Scheme != \"gs\" {\n\t\treturn \"\", \"\", errors.Errorf(\"object %s must have 'gs' scheme\", object)\n\t}\n\tif parsed.Host == \"\" {\n\t\treturn \"\", \"\", errors.Errorf(\"object %s must have bucket\", object)\n\t}\n\tif parsed.Path == \"\" {","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/util/gcsx/gcs.go#L111-L147","documentation":"MakeObject builds a gs:// object path from a bucket and path and panics if the bucket string is empty, since a GCS path without a bucket is meaningless. It is a fail-fast guard for a programmer/config error rather than a runtime condition.","triggerScenarios":"Calling gcsx.MakeObject(\"\", \"some/path\"), or calling it via Join/CommitManifest/PutArtifact with a path derived from an empty bucket — e.g. an unset or empty --artifact/staging bucket flag.","commonSituations":"Missing command-line flag for staging/artifact bucket; empty GCS_BUCKET environment variable; a pipeline option defaulting to \"\" that is fed straight into MakeObject.","solutions":["Ensure the bucket value is set and non-empty before calling MakeObject","Check the flag/env variable supplying the bucket (e.g. --staging_location, GCS bucket option)","Add an explicit empty-string check with a helpful message before constructing the path","Parse a full gs:// path with ParseObject to derive the bucket instead of hardcoding \"\""],"exampleFix":"// before\nobj := gcsx.MakeObject(bucket, path) // panics when bucket == \"\"\n// after\nif bucket == \"\" {\n\treturn fmt.Errorf(\"--staging_bucket must be set\")\n}\nobj := gcsx.MakeObject(bucket, path)","handlingStrategy":"validation","validationCode":"if bucket == \"\" {\n\treturn fmt.Errorf(\"bucket must be provided (check --staging_location / GCS config)\")\n}","typeGuard":"func hasBucket(object string) bool { b, _ := gcsx.ParseObject(object); return b != \"\" }","tryCatchPattern":null,"preventionTips":["Always populate bucket flags/env vars before constructing GCS paths","Fail early at config-load time when required bucket options are empty","Derive buckets from ParseObject on full gs:// URLs rather than manual splitting"],"tags":["go","gcs","panic","configuration"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}