evanw/esbuild · error

[ ] filter is not a valid Go regular expression

Error message

[%s] %q filter is not a valid Go regular expression: %q

What it means

Thrown when a plugin provides a filter that fails Go's regexp.Compile, meaning it is not valid RE2 regular expression syntax. esbuild uses Go's regexp engine (RE2) which does not support backreferences, lookbehind, or lookahead. The error includes the plugin name, the kind (filter/namespace), and the offending pattern.

Solutions

  1. Remove RE2-unsupported features: no backreferences (\1), no lookahead/lookbehind ((?=...), (?<=...))
  2. Validate the pattern with an RE2-compatible tester or Go's regexp.Compile before deploying the plugin
  3. Simplify the regex and test incrementally to isolate the syntax error

Example fix

// before
build.onResolve({ filter: '\\b(foo)\\1' }, handler)
// after
build.onResolve({ filter: '\\bfoo' }, handler)
Defensive patterns

Strategy: validation

Validate before calling

import { RE2 } from 're2-wasm' // or use a Go RE2 reference
function isValidRE2(pattern) {
  try {
    new RegExp(pattern) // JS RegExp is close to RE2 for basic patterns
    return !/\(\?.*[=!<>]/.test(pattern) // reject lookahead/lookbehind
  } catch {
    return false
  }
}
if (!isValidRE2(filter)) throw new Error(`Filter '${filter}' is not valid RE2`)

Prevention

When it happens

Trigger: Setting a plugin filter to a regex with unsupported syntax such as backreferences (\1), lookaheads ((?=...)), unbalanced parentheses, or invalid escape sequences.

Common situations: Plugin authors familiar with PCRE/JavaScript regex who use features not in RE2 (backreferences, lookahead/lookbehind), or who have a typo like an unescaped special character.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/306d1a9a1d5a4384. Report an issue: GitHub.

Appendix: source

Thrown at internal/config/config.go:763

	// Cache for next time
	filterMutex.Lock()
	defer filterMutex.Unlock()
	if filterCache == nil {
		filterCache = make(map[string]*regexp.Regexp)
	}
	filterCache[filter] = result
	return
}

func CompileFilterForPlugin(pluginName string, kind string, filter string) (*regexp.Regexp, error) {
	if filter == "" {
		return nil, fmt.Errorf("[%s] %q is missing a filter", pluginName, kind)
	}

	result := compileFilter(filter)
	if result == nil {
		return nil, fmt.Errorf("[%s] %q filter is not a valid Go regular expression: %q", pluginName, kind, filter)
	}

	return result, nil
}

func PluginAppliesToPath(path logger.Path, filter *regexp.Regexp, namespace string) bool {
	return (namespace == "" || path.Namespace == namespace) && filter.MatchString(path.Text)
}

////////////////////////////////////////////////////////////////////////////////
// Plugin API

type Plugin struct {
	Name      string
	OnStart   []OnStart
	OnResolve []OnResolve
	OnLoad    []OnLoad
}

View on GitHub (pinned to f6058f8364)