charmbracelet/crush · error

failed to search for symbol: %w

Error message

failed to search for symbol: %w

What it means

resolveSymbolResults falls back to grep (searchFiles) when locating a symbol for LSP operations. If grep itself fails, the error is wrapped as 'failed to search for symbol', hiding the underlying cause (e.g. invalid regex from error 140 or walker failures).

Source

Thrown at internal/agent/tools/lsp_helpers.go:61

	// All candidates were rejected by the LSP; return the first one
	// so the caller gets a meaningful error from their own LSP call.
	return results[0], nil
}

// resolveSymbolResults greps for a symbol and returns all viable
// {client, path, position} tuples. Callers that need just one match
// (definition, rename, call hierarchy) use resolveSymbol; callers that
// want to iterate all matches (references) use this directly.
func resolveSymbolResults(ctx context.Context, lspManager *lsp.Manager, symbol, workingDir string) ([]*resolvedSymbol, error) {
	lspManager.Start(ctx, workingDir)

	// Use word boundaries to avoid matching inside larger identifiers
	// (e.g. "Bar" inside "myBar"). The symbol is already QuoteMeta'd
	// so dots and other regex metacharacters are escaped.
	pattern := `\b` + regexp.QuoteMeta(symbol) + `\b`
	matches, _, err := searchFiles(ctx, pattern, workingDir, "", 100)
	if err != nil {
		return nil, fmt.Errorf("failed to search for symbol: %w", err)
	}
	if len(matches) == 0 {
		return nil, fmt.Errorf("symbol '%s' not found in grep results", symbol)
	}

	var results []*resolvedSymbol
	for _, match := range matches {
		absPath, err := filepath.Abs(match.path)
		if err != nil {
			continue
		}

		client := findLSPClient(lspManager, absPath)
		if client == nil {
			continue
		}

		results = append(results, &resolvedSymbol{

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Read the wrapped error to identify the root cause (likely 'invalid regex pattern' or a filesystem error).
  2. Ensure the symbol parameter is a non-empty identifier.
  3. Retry the search; if persistent, verify the working directory is readable.
  4. Check that the symbol doesn't contain characters that break QuoteMeta-embedded patterns (rare, QuoteMeta handles metacharacters).

Example fix

// before
resolveSymbol(ctx, "", workingDir) // empty symbol
// after
resolveSymbol(ctx, "MyFunction", workingDir)
Defensive patterns

Strategy: try-catch

Validate before calling

if symbol == "" {
    return errors.New("symbol must be non-empty")
}

Type guard

null

Try / catch

resolved, err := resolveSymbol(ctx, sym, dir)
if err != nil {
    if strings.Contains(err.Error(), "failed to search") {
        // inspect wrapped cause: regex or walker error
    }
}

Prevention

When it happens

Trigger: Calling resolveSymbol (used by LSP goto-definition/references/rename helpers) when the underlying grep search errors — most commonly because the symbol string, once embedded in the \\b-quoted pattern, is empty or the walker fails.

Common situations: Empty symbol parameter producing a degenerate pattern, grep running in a directory that cannot be walked, or cascading from an invalid include pattern.

Related errors


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