apache/beam · error

invalid glob pattern

Error message

invalid glob pattern: %w

What it means

The in-memory filesystem's List matches every stored key against the glob using filesystem.Match; if the glob itself is syntactically invalid, Match returns an error which List wraps as 'invalid glob pattern: %w'. This validates patterns eagerly even when the store is empty.

Solutions

  1. Fix the glob syntax before calling List.
  2. Test the pattern with filesystem.Match directly to get the raw syntax error.
  3. Pre-validate patterns in test helpers to fail with clearer messages.
  4. Avoid shell-specific glob constructs not supported by filesystem.Match.

Example fix

// before
glob := "memfs://data[0-9" // invalid
files, err := fs.List(ctx, glob)
// after
glob := "memfs://data[0-9]*"
files, err := fs.List(ctx, glob)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := filesystem.Match(globNoScheme, "probe"); err != nil {
	return fmt.Errorf("glob %q is invalid: %w", glob, err)
}

Try / catch

files, err := fs.List(ctx, glob)
if err != nil && strings.Contains(err.Error(), "invalid glob pattern") {
	return fmt.Errorf("check memfs glob %q: %w", glob, err)
}

Prevention

When it happens

Trigger: Calling fs.List(ctx, glob) on a memfs filesystem with a malformed pattern (e.g. unclosed '[' , invalid '**' usage) that filesystem.Match rejects.

Common situations: Unit-test fixtures with hand-written bad globs; dynamically generated patterns with truncated bracket classes; mixing GCS-style patterns with memfs semantics.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/0be3175e487e3562. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/io/filesystem/memfs/memory.go:80

	return instance
}

func (f *fs) Close() error {
	return nil
}

func (f *fs) List(_ context.Context, glob string) ([]string, error) {
	f.mu.Lock()
	defer f.mu.Unlock()

	// As with other functions, the memfs:// prefix is optional.
	globNoScheme := strings.TrimPrefix(glob, "memfs://")

	var ret []string
	for k := range f.m {
		matched, err := filesystem.Match(globNoScheme, strings.TrimPrefix(k, "memfs://"))
		if err != nil {
			return nil, fmt.Errorf("invalid glob pattern: %w", err)
		}
		if matched {
			ret = append(ret, k)
		}
	}
	sort.Strings(ret)
	return ret, nil
}

func (f *fs) OpenRead(_ context.Context, filename string) (io.ReadCloser, error) {
	f.mu.Lock()
	defer f.mu.Unlock()

	if v, ok := f.m[normalize(filename)]; ok {
		return io.NopCloser(bytes.NewReader(v.Data)), nil
	}
	return nil, os.ErrNotExist
}

View on GitHub (pinned to 12126d8942)