evanw/esbuild · error
[%s] %q is missing a filter
Error message
[%s] %q is missing a filter
What it means
Returned by config.CompileFilterForPlugin when a plugin's OnResolve or OnLoad callback is registered with an empty Filter string. esbuild uses the filter as a precompiled Go regular expression to cheaply decide which import paths invoke the callback; an empty filter is rejected because it would either match nothing useful or force the callback to run on every path (a performance footgun). The error names the plugin and the callback kind ('OnResolve' or 'OnLoad').
Source
Thrown at internal/config/config.go:758
// Cache miss
result, err := regexp.Compile(filter)
if err != nil {
return nil
}
// 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 {View on GitHub (pinned to 6ff1d8b0d8)
Solutions
- Provide a non-empty Go RE2 regex for the filter, e.g. filter: '\.css$' or a catch-all filter: '.' if you truly want every path.
- If the callback should apply to a specific namespace only, still supply a filter (use '.' to match all) plus the namespace option.
- Double-check that the filter variable is not conditionally set to '' by a config-driven code path.
- Test the plugin in isolation to surface the error before wiring it into a larger build pipeline.
Example fix
// before
build({ plugins: [{ name: 'x', setup(b) { b.onResolve({ filter: '' }, () => {...}) } }] })
// after
build({ plugins: [{ name: 'x', setup(b) { b.onResolve({ filter: /\.css$/ }, () => {...}) } }] }) Defensive patterns
Strategy: validation
Validate before calling
// Reject plugin registrations with empty filters before build.
function assertFilter(plugin, kind, filter) {
if (typeof filter !== 'string' || filter.length === 0) {
throw new Error(`Plugin ${plugin}: ${kind} requires a non-empty regex filter`)
}
} Type guard
function isNonEmptyFilter(f: unknown): f is string {
return typeof f === 'string' && f.length > 0
} Try / catch
try {
await esbuild.build({ plugins, ... })
} catch (e) {
if (/missing a filter/i.test(e.message)) {
console.error('A plugin callback was registered without a filter:', e.message)
// surface plugin name from the message and patch its setup()
}
throw e
} Prevention
- Always pair onResolve/onLoad with a filter; use '.' to match everything if unsure.
- Author a tiny plugin-test harness that builds with a no-op entry to catch filter errors early.
- Type plugin option filters as a branded NonEmptyString to make emptiness a compile error.
When it happens
Trigger: Register a plugin whose setup() calls onResolve({ filter: '', namespace: ... }, fn) or onLoad({ filter: '', namespace: ... }, fn) with an empty/missing filter. Reproduces in both the JS API (via the service protocol) and the Go API (pkg/api). Triggered during build context creation, before any file is bundled.
Common situations: Migrating a webpack/rollup plugin to esbuild and forgetting esbuild mandates a regex filter; building a plugin dynamically where the filter variable is conditionally empty; assuming filter is optional (it is required for onResolve/onLoad).
Related errors
- [%s] %q filter is not a valid Go regular expression: %q
- onResolve() call is missing a filter
- onLoad() call is missing a filter
- Invalid path suffix %q returned from plugin (must start with
- Expected onResolve() callback in plugin ${quote(name)} to re
AI-assisted analysis of evanw/esbuild@6ff1d8b0d8 (2026-08-03).
Data as JSON: /data/errors/1cfb89bba5c3a3af.json.
Report an issue: GitHub.