{"record":{"id":"73c9473c337f3b9b","repo":"apache/beam","slug":"bucket-must-not-be-empty","errorCode":null,"errorMessage":"bucket must not be empty","messagePattern":"bucket must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/io/filesystem/s3/util.go","lineNumber":37,"sourceCode":"\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n)\n\n// parseURI deconstructs the S3 uri in the format 's3://bucket/key' to (bucket, key)\nfunc parseURI(uri string) (string, string, error) {\n\tparsed, err := url.Parse(uri)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\tif parsed.Scheme != \"s3\" {\n\t\treturn \"\", \"\", errors.New(\"scheme must be 's3'\")\n\t}\n\n\tbucket := parsed.Host\n\tif bucket == \"\" {\n\t\treturn \"\", \"\", errors.New(\"bucket must not be empty\")\n\t}\n\n\tvar key string\n\tif parsed.Path != \"\" {\n\t\tkey = parsed.Path[1:]\n\t}\n\n\treturn bucket, key, nil\n}\n\n// makeURI constructs an S3 uri from the bucket and key to the format 's3://bucket/key'\nfunc makeURI(bucket string, key string) string {\n\treturn fmt.Sprintf(\"s3://%s/%s\", bucket, key)\n}\n","sourceCodeStart":19,"sourceCodeEnd":52,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/filesystem/s3/util.go#L19-L52","documentation":"parseURI in the Beam S3 filesystem adapter splits an s3:// URI into bucket and key. It throws this error when the URI has the s3 scheme but an empty host, i.e. no bucket component. This guards List, OpenRead, OpenWrite, Size, LastModified and Remove from issuing S3 API calls with an invalid bucket.","triggerScenarios":"Calling any s3 filesystem operation (e.g. filesystem.List(ctx, 's3:///path/to/file'), OpenRead, OpenWrite, Size, LastModified, Remove) with a URI like \"s3:///key\" or \"s3://\" where the host portion between 's3://' and the next '/' is empty.","commonSituations":"Programmatically assembled URIs where a bucket variable was empty or unexpanded (missing pipeline option / template parameter); strings built with fmt.Sprintf(\"s3:///%s\", key) using an extra slash; config placeholders like ${BUCKET} left unresolved in Beam pipeline options.","solutions":["Inspect the s3:// path being passed and ensure it includes a non-empty bucket: s3://my-bucket/key.","If the bucket comes from a pipeline option or template parameter, verify it is set and not an empty/unexpanded ${VAR} placeholder.","Strip accidental double slashes when building URIs: use url.JoinPath or fmt.Sprintf(\"s3://%s/%s\", bucket, key) with a trimmed key."],"exampleFix":"// before\npath := fmt.Sprintf(\"s3:///%s\", key) // bucket empty\n// after\npath := fmt.Sprintf(\"s3://%s/%s\", bucket, strings.TrimPrefix(key, \"/\"))","handlingStrategy":"validation","validationCode":"u, err := url.Parse(path)\nif err != nil || u.Scheme != \"s3\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid s3 path %q: bucket must not be empty\", path)\n}","typeGuard":"func isValidS3URI(path string) bool {\n    u, err := url.Parse(path)\n    return err == nil && u.Scheme == \"s3\" && u.Host != \"\"\n}","tryCatchPattern":"if _, _, err := parseURI(path); err != nil {\n    return fmt.Errorf(\"s3 filesystem: %w\", err)\n}","preventionTips":["Build s3 URIs with fmt.Sprintf(\"s3://%s/%s\", bucket, key) instead of string concatenation.","Validate bucket pipeline options are non-empty at pipeline construction time.","Add a unit test asserting every s3 path in your config resolves to a valid bucket/key pair."],"tags":["go","s3","apache-beam","io","url-validation"],"backgroundTag":"empty-required-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}