charmbracelet/crush · error

invalid regex pattern: %w

Error message

invalid regex pattern: %w

What it means

The grep tool compiles the user-supplied search pattern through a regex cache before walking files. When Go's regexp package cannot compile the pattern, the compile error is wrapped as 'invalid regex pattern'. This prevents an invalid pattern from aborting the file walker mid-run.

Source

Thrown at internal/agent/tools/grep.go:293

			Text string `json:"text"`
		} `json:"path"`
		Lines struct {
			Text string `json:"text"`
		} `json:"lines"`
		LineNumber int `json:"line_number"`
		Submatches []struct {
			Start int `json:"start"`
		} `json:"submatches"`
	} `json:"data"`
}

func searchFilesWithRegex(pattern, rootPath, include string) ([]grepMatch, error) {
	matches := []grepMatch{}

	// Use cached regex compilation
	regex, err := searchRegexCache.get(pattern)
	if err != nil {
		return nil, fmt.Errorf("invalid regex pattern: %w", err)
	}

	var includePattern *regexp.Regexp
	if include != "" {
		regexPattern := globToRegex(include)
		includePattern, err = globRegexCache.get(regexPattern)
		if err != nil {
			return nil, fmt.Errorf("invalid include pattern: %w", err)
		}
	}

	// Create walker with gitignore and crushignore support
	walker := fsext.NewFastGlobWalker(rootPath)

	err = filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil // Skip errors
		}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Fix the regex syntax: check for unbalanced parens/brackets and escape metacharacters with \\.
  2. Validate the pattern first with regexp.Compile in a test or REPL before running the search.
  3. Replace RE2-unsupported constructs (lookaheads/lookbehinds/backreferences) with supported equivalents.
  4. If the pattern came from untrusted input, wrap it with regexp.QuoteMeta to treat it literally.

Example fix

// before
searchFilesWithRegex("foo(?=bar)", root, "")
// after
searchFilesWithRegex("foobar", root, "") // or use a two-pass search instead of lookahead
Defensive patterns

Strategy: validation

Validate before calling

if _, err := regexp.Compile(pattern); err != nil {
    return fmt.Errorf("bad pattern %q: %w", pattern, err)
}

Type guard

func isValidRegex(p string) bool { _, err := regexp.Compile(p); return err == nil }

Try / catch

if err != nil {
    var re *regexp.SyntaxError
    if errors.As(err, &re) { /* surface syntax position */ }
}

Prevention

When it happens

Trigger: Calling the grep tool (via searchFiles) with a pattern that is not valid Go regexp syntax, e.g. unbalanced parentheses, a trailing backslash, or an invalid character class like '[a-'.

Common situations: Users typing shell-glob-style patterns ('*.go') instead of regex, copying PCRE-only syntax like lookaheads '(?=...)' which Go's RE2 engine does not support, or a model-generated pattern with unescaped special characters.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/88e6bd64524fdf79. Report an issue: GitHub.