{"record":{"id":"1cfb89bba5c3a3af","repo":"evanw/esbuild","slug":"s-q-is-missing-a-filter","errorCode":null,"errorMessage":"[%s] %q is missing a filter","messagePattern":"\\[(.+?)\\] %q is missing a filter","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/config.go","lineNumber":758,"sourceCode":"\t// Cache miss\n\tresult, err := regexp.Compile(filter)\n\tif err != nil {\n\t\treturn nil\n\t}\n\n\t// Cache for next time\n\tfilterMutex.Lock()\n\tdefer filterMutex.Unlock()\n\tif filterCache == nil {\n\t\tfilterCache = make(map[string]*regexp.Regexp)\n\t}\n\tfilterCache[filter] = result\n\treturn\n}\n\nfunc CompileFilterForPlugin(pluginName string, kind string, filter string) (*regexp.Regexp, error) {\n\tif filter == \"\" {\n\t\treturn nil, fmt.Errorf(\"[%s] %q is missing a filter\", pluginName, kind)\n\t}\n\n\tresult := compileFilter(filter)\n\tif result == nil {\n\t\treturn nil, fmt.Errorf(\"[%s] %q filter is not a valid Go regular expression: %q\", pluginName, kind, filter)\n\t}\n\n\treturn result, nil\n}\n\nfunc PluginAppliesToPath(path logger.Path, filter *regexp.Regexp, namespace string) bool {\n\treturn (namespace == \"\" || path.Namespace == namespace) && filter.MatchString(path.Text)\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Plugin API\n\ntype Plugin struct {","sourceCodeStart":740,"sourceCodeEnd":776,"githubUrl":"https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/config/config.go#L740-L776","documentation":"Thrown by esbuild's CompileFilterForPlugin when a plugin's OnResolve or OnLoad registration passes an empty string as the filter argument. esbuild plugins require a non-empty Go RE2 regular expression for every filter so that the callback knows which import paths to intercept. The %s is the plugin name and %q is the 'filter' or 'namespace' kind label.","triggerScenarios":"Registering a plugin and calling build.onResolve({ filter: '' }, handler) or build.onLoad({ filter: '' }, handler) with an empty filter string in the setup callback.","commonSituations":"Plugin authors who dynamically construct a filter regex that evaluates to an empty string at runtime, or who copy a plugin template and forget to fill in the filter field.","solutions":["Provide a non-empty Go RE2 regex string as the filter, e.g. '.*' to match all paths or '.+\\.svg$' for specific extensions","If your plugin should match every import, use the regex '.*'","If the filter is computed dynamically, add a guard that falls back to '.*' when the computed value is empty"],"exampleFix":"// before\nbuild.onResolve({ filter: '' }, handler)\n// after\nbuild.onResolve({ filter: '.*' }, handler)","handlingStrategy":"validation","validationCode":"function validatePluginFilter(filter) {\n  if (!filter || filter.trim() === '') {\n    throw new Error('Plugin filter must be a non-empty string')\n  }\n}\nvalidatePluginFilter(myFilter)\nbuild.onResolve({ filter: myFilter || '.*' }, handler)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always provide a filter when registering onResolve/onLoad callbacks","If the filter is computed dynamically, default to '.*' when empty","Add a linting step that checks plugin registrations for non-empty filters"],"tags":["esbuild","plugin","regex","filter","config"],"backgroundTag":null,"analyzedSha":"f6058f8364fe7ab91ca57a83e02577ed74c9cae4","analyzedAt":"2026-08-09T18:37:22.223Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}