{"record":{"id":"16009d977b946202","repo":"apache/beam","slug":"invalid-glob-pattern-q-w","errorCode":null,"errorMessage":"invalid glob pattern %q: %w","messagePattern":"invalid glob pattern %q: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/io/filesystem/gcs/gcs.go","lineNumber":189,"sourceCode":"}\n\nfunc (f *fs) Close() error {\n\treturn f.client.Close()\n}\n\nfunc (f *fs) List(ctx context.Context, glob string) ([]string, error) {\n\tbucket, object, err := gcsx.ParseObject(glob)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Compile the glob pattern to a regex. We use a custom glob-to-regex\n\t// translation that treats / as a regular character (not a separator),\n\t// since GCS object names are flat. This also supports ** for recursive\n\t// matching, similar to the Java and Python SDKs.\n\tre, err := globToRegex(object)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid glob pattern %q: %w\", object, err)\n\t}\n\n\tvar candidates []string\n\n\t// We handle globs by list all candidates and matching them here.\n\t// For now, we assume * is the first matching character to make a\n\t// prefix listing and not list the entire bucket.\n\tprefix := fsx.GetPrefix(object)\n\tit := f.client.Bucket(bucket).UserProject(billingProject).Objects(ctx, &storage.Query{\n\t\tPrefix: prefix,\n\t})\n\tfor {\n\t\tobj, err := it.Next()\n\t\tif err == iterator.Done {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/filesystem/gcs/gcs.go#L171-L207","documentation":"List on the GCS filesystem compiles the object-name glob into a regex before listing candidates; if globToRegex fails (e.g. unclosed '[' character class), the syntax error is wrapped as 'invalid glob pattern %q: %w'. No GCS request is made — this is purely client-side pattern validation.","triggerScenarios":"Calling fs.List(ctx, glob) with a malformed glob such as an unclosed character class, or any other pattern globToRegex cannot translate.","commonSituations":"Dynamically assembled paths with truncated bracket expressions; users porting shell globs with shell-specific semantics; typos in pattern strings.","solutions":["Correct the glob syntax (close the '[' character class, remove invalid tokens).","Escape literal brackets in the pattern.","Validate the pattern client-side (filesystem.Match or a compile check) before List.","Log the exact pattern string passed in, since interpolation errors are common."],"exampleFix":"// before\nfiles, err := fs.List(ctx, \"gs://b/data[202\")\n// after\nfiles, err := fs.List(ctx, \"gs://b/data[202[3]]\") // or fix/escape the class","handlingStrategy":"validation","validationCode":"func validGCSGlob(p string) error {\n\tdepth := 0\n\tfor _, r := range p {\n\t\tif r == '[' { depth++ }\n\t\tif r == ']' { depth--; if depth < 0 { return errors.New(\"unmatched ]\") } }\n\t}\n\tif depth != 0 { return errors.New(\"unclosed '['\") }\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := fs.List(ctx, object); err != nil && strings.Contains(err.Error(), \"invalid glob pattern\") {\n\treturn fmt.Errorf(\"fix pattern %q: %w\", object, err)\n}","preventionTips":["Lint user-supplied globs before building the pipeline.","Escape literal brackets and special characters.","Log the final pattern string to catch interpolation bugs.","Keep patterns in config reviewed/tested like code."],"tags":["go","apache-beam","gcs","glob","regex"],"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"}