{"record":{"id":"5538f273847c2592","repo":"charmbracelet/crush","slug":"invalid-include-pattern-w","errorCode":null,"errorMessage":"invalid include pattern: %w","messagePattern":"invalid include pattern: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/grep.go","lineNumber":301,"sourceCode":"\t\t} `json:\"submatches\"`\n\t} `json:\"data\"`\n}\n\nfunc searchFilesWithRegex(pattern, rootPath, include string) ([]grepMatch, error) {\n\tmatches := []grepMatch{}\n\n\t// Use cached regex compilation\n\tregex, err := searchRegexCache.get(pattern)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid regex pattern: %w\", err)\n\t}\n\n\tvar includePattern *regexp.Regexp\n\tif include != \"\" {\n\t\tregexPattern := globToRegex(include)\n\t\tincludePattern, err = globRegexCache.get(regexPattern)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid include pattern: %w\", err)\n\t\t}\n\t}\n\n\t// Create walker with gitignore and crushignore support\n\twalker := fsext.NewFastGlobWalker(rootPath)\n\n\terr = filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn nil // Skip errors\n\t\t}\n\n\t\tif info.IsDir() {\n\t\t\t// Check if directory should be skipped\n\t\t\tif walker.ShouldSkip(path) {\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\t\t\treturn nil // Continue into directory\n\t\t}","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/grep.go#L283-L319","documentation":"When an 'include' glob filter is provided, it is converted to a regex with globToRegex and compiled through a cache. If that derived regex fails to compile, the error is wrapped as 'invalid include pattern'. The search pattern itself is valid; only the file-filtering glob is bad.","triggerScenarios":"Calling the grep tool with an include parameter whose glob-to-regex translation yields an uncompilable regexp, e.g. pathological character classes or malformed brace expansions in the include string.","commonSituations":"Typing include filters like '**/*.{go,rs' with unbalanced braces, or platform-specific path separators slipping into the include argument.","solutions":["Use a simple, well-formed glob such as '*.go' or '**/*.ts'.","Check for unbalanced braces or brackets in the include string.","Omit the include parameter to search all files, then filter results manually."],"exampleFix":"// before\nsearchFiles(pattern, root, \"**/*.{go,\")\n// after\nsearchFiles(pattern, root, \"**/*.go\")","handlingStrategy":"validation","validationCode":"re := globToRegex(include)\nif _, err := regexp.Compile(re); err != nil {\n    return fmt.Errorf(\"bad include %q: %w\", include, err)\n}","typeGuard":"null","tryCatchPattern":"if err != nil {\n    return nil, fmt.Errorf(\"include filter rejected: %w\", err)\n}","preventionTips":["Use simple globs like '*.go' or '**/*.ts'","Check brace/bracket balance in include filters","Test glob-to-regex conversion in unit tests"],"tags":["regex","glob","grep"],"backgroundTag":"invalid-glob-pattern","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}