sinelaw/fresh · error
grep exited with code
Error message
grep exited with code ${r.exit_code}: ${r.stderr} What it means
The live_grep plugin's plain `grep` provider throws this when GNU/BSD grep exits with a code other than 0 (matches) or 1 (no matches — parsed as an empty result). Any other code (commonly 2) means grep failed: an invalid pattern, unreadable files, or bad flags. grep's stderr is included in the message.
Solutions
- Fix the query pattern if regex mode is on (use POSIX-compatible syntax).
- Install ripgrep so the higher-priority rg provider is used instead of the grep fallback.
- Run `grep -rn <pattern> .` manually in the cwd and read stderr to identify flag/pattern issues.
- Check which grep is in PATH (GNU vs BSD) and align flag expectations.
Defensive patterns
Strategy: fallback
Validate before calling
if (regexMode) { try { new RegExp(query); } catch { throw new Error(`invalid regex: ${query}`); } }
try { await editor.spawnProcess("grep", ["--version"], cwd); } catch { /* no grep either */ } Type guard
function isGrepExitOk(r) { return r.exit_code === 0 || r.exit_code === 1; } Try / catch
try {
results = await grepProvider.search(query, opts);
} catch (e) {
if (/grep exited with code 2/.test(String(e))) {
results = await grepProvider.search(query, { ...opts, regex: false });
} else { throw e; }
} Prevention
- Install ripgrep so the grep fallback is rarely used.
- Use POSIX BRE/ERE-safe patterns on the fallback path.
- Watch for GNU vs BSD grep flag differences (especially on macOS).
- Validate regex queries before enabling regex mode.
When it happens
Trigger: Calling live-grep with the grep (fallback) provider when: (1) the query is an invalid BRE/ERE pattern (grep exit 2), (2) flags built by the plugin are unsupported by the installed grep flavor (e.g. BSD vs GNU differences for -P/--include style options), or (3) the cwd cannot be read.
Common situations: Systems without ripgrep where the grep fallback runs and the user's regex uses PCRE syntax GNU grep -P would reject or BSD grep doesn't support; macOS BSD grep choking on GNU-only flags; malformed patterns like '[' in regex mode.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- rg exited with code
- ag exited with code
- ack exited with code
- git grep exited with code
- ${provider.name}: ${e instanceof Error ? e.message …
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/818ab24ddd0e9156.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/plugins/live_grep.ts:639
},
search: async (query, { cwd, maxResults, wholeWord, regex }) => {
const args = [
"-rn",
"-I",
"--exclude-dir=.git",
"--exclude-dir=node_modules",
"--exclude-dir=target",
];
args.push(regex === false ? "-F" : "-E");
if (wholeWord) args.push("-w");
args.push("--", query, ".");
const r = await editor.spawnProcess("grep", args, cwd);
if (r.exit_code === 0 || r.exit_code === 1) {
// grep emits `path:line:content` (no column). parseGrepOutput's
// 3-field fallback handles the missing column (defaults to 1).
return parseGrepOutput(r.stdout, maxResults, (msg) => editor.debug(msg)) as GrepMatch[];
}
throw new Error(`grep exited with code ${r.exit_code}: ${r.stderr}`);
},
});
// ── Wiring ──────────────────────────────────────────────────────
function badgeFor(source: ScopeId | undefined): string {
if (!source || source === "files") return "";
const def = SCOPES.find((s) => s.id === source);
return def?.badge ? `[${def.badge}] ` : "";
}
const finder = new Finder<GrepMatch>(editor, {
id: "live-grep",
format: (match) => ({
label: `${badgeFor(match.source)}${match.file}:${match.line}`,
description:
match.content.length > 60
? match.content.substring(0, 57).trim() + "..."View on GitHub (pinned to 67894ca546)