{"record":{"id":"0597e5f206367c78","repo":"apache/beam","slug":"invalid-key-pattern-s","errorCode":null,"errorMessage":"invalid key pattern: %s","messagePattern":"invalid key pattern: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/io/filesystem/s3/s3.go","lineNumber":105,"sourceCode":"\tprefix := fsx.GetPrefix(keyPattern)\n\tparams := &s3.ListObjectsV2Input{\n\t\tBucket: aws.String(bucket),\n\t\tPrefix: aws.String(prefix),\n\t}\n\tpaginator := s3.NewListObjectsV2Paginator(f.client, params)\n\n\tvar objects []string\n\tfor paginator.HasMorePages() {\n\t\toutput, err := paginator.NextPage(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error retrieving page: %v\", err)\n\t\t}\n\n\t\tfor _, object := range output.Contents {\n\t\t\tkey := aws.ToString(object.Key)\n\t\t\tmatch, err := filepath.Match(keyPattern, key)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid key pattern: %s\", keyPattern)\n\t\t\t}\n\n\t\t\tif match {\n\t\t\t\tobjects = append(objects, key)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn objects, nil\n}\n\n// OpenRead returns a new io.ReadCloser to read contents from the file. The caller must call Close\n// on the returned io.ReadCloser when done reading.\nfunc (f *fs) OpenRead(ctx context.Context, filename string) (io.ReadCloser, error) {\n\tbucket, key, err := parseURI(filename)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing S3 uri %s: %v\", filename, err)\n\t}","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/filesystem/s3/s3.go#L87-L123","documentation":"This is returned when filepath.Match fails to compile the caller-supplied glob keyPattern against a key. filepath.Match returns ErrBadPattern for malformed patterns like an unterminated '[' escape. Note the actual pattern (not the underlying error) is reported, which can obscure the root cause.","triggerScenarios":"Passing a glob with bad syntax to List(), e.g. 's3://bucket/data[abc' (unclosed character class) or a trailing lone backslash; the error fires on the first object key checked.","commonSituations":"Users constructing patterns by string concatenation accidentally producing unbalanced brackets; porting shell globs with syntax filepath.Match doesn't support (e.g. '**').","solutions":["Fix the glob pattern syntax: balance all '[' ... ']' character classes.","Remember filepath.Match has no '**' — use '*' per path segment.","Pre-validate the pattern with filepath.Match(pattern, \"\") and check for filepath.ErrBadPattern before calling List.","If the pattern comes from user config, add validation at config load time."],"exampleFix":"// before\nkeys, err := fs.List(ctx, \"s3://bucket/data[abc\")\n// after\nif _, err := filepath.Match(\"data[abc\", \"probe\"); err != nil {\n  return fmt.Errorf(\"bad glob: %w\", err)\n}\nkeys, err := fs.List(ctx, \"s3://bucket/data[abc]\")","handlingStrategy":"validation","validationCode":"func validGlob(pattern string) bool {\n  _, err := filepath.Match(pattern, \"probe\")\n  return err == nil // false when pattern has filepath.ErrBadPattern\n}","typeGuard":null,"tryCatchPattern":"match, err := filepath.Match(keyPattern, key)\nif errors.Is(err, filepath.ErrBadPattern) {\n  return fmt.Errorf(\"glob %q is malformed (check [ ] classes): %w\", keyPattern, err)\n}","preventionTips":["Pre-validate globs with filepath.Match(pattern, \"\") before calling List.","Avoid '**' — filepath.Match doesn't support it.","Ensure character classes '[...]' are closed and contain no stray escapes.","Escape literal '[' or '?' with brackets if needed."],"tags":["s3","glob","pattern","validation"],"backgroundTag":"invalid-regex-pattern","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"}