{"record":{"id":"818ab24ddd0e9156","repo":"sinelaw/fresh","slug":"grep-exited-with-code-r-exit-code-r-stderr","errorCode":null,"errorMessage":"grep exited with code ${r.exit_code}: ${r.stderr}","messagePattern":"grep exited with code (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/plugins/live_grep.ts","lineNumber":639,"sourceCode":"  },\n  search: async (query, { cwd, maxResults, wholeWord, regex }) => {\n    const args = [\n      \"-rn\",\n      \"-I\",\n      \"--exclude-dir=.git\",\n      \"--exclude-dir=node_modules\",\n      \"--exclude-dir=target\",\n    ];\n    args.push(regex === false ? \"-F\" : \"-E\");\n    if (wholeWord) args.push(\"-w\");\n    args.push(\"--\", query, \".\");\n    const r = await editor.spawnProcess(\"grep\", args, cwd);\n    if (r.exit_code === 0 || r.exit_code === 1) {\n      // grep emits `path:line:content` (no column). parseGrepOutput's\n      // 3-field fallback handles the missing column (defaults to 1).\n      return parseGrepOutput(r.stdout, maxResults, (msg) => editor.debug(msg)) as GrepMatch[];\n    }\n    throw new Error(`grep exited with code ${r.exit_code}: ${r.stderr}`);\n  },\n});\n\n// ── Wiring ──────────────────────────────────────────────────────\n\nfunction badgeFor(source: ScopeId | undefined): string {\n  if (!source || source === \"files\") return \"\";\n  const def = SCOPES.find((s) => s.id === source);\n  return def?.badge ? `[${def.badge}] ` : \"\";\n}\n\nconst finder = new Finder<GrepMatch>(editor, {\n  id: \"live-grep\",\n  format: (match) => ({\n    label: `${badgeFor(match.source)}${match.file}:${match.line}`,\n    description:\n      match.content.length > 60\n        ? match.content.substring(0, 57).trim() + \"...\"","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/plugins/live_grep.ts#L621-L657","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if (regexMode) { try { new RegExp(query); } catch { throw new Error(`invalid regex: ${query}`); } }\ntry { await editor.spawnProcess(\"grep\", [\"--version\"], cwd); } catch { /* no grep either */ }","typeGuard":"function isGrepExitOk(r) { return r.exit_code === 0 || r.exit_code === 1; }","tryCatchPattern":"try {\n  results = await grepProvider.search(query, opts);\n} catch (e) {\n  if (/grep exited with code 2/.test(String(e))) {\n    results = await grepProvider.search(query, { ...opts, regex: false });\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["grep","external-process","search","exit-code"],"backgroundTag":"git-command-failed","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}