sinelaw/fresh · error

git grep exited with code

Error message

git grep exited with code ${r.exit_code}: ${r.stderr}

What it means

The live_grep plugin's `git grep` provider throws this when the spawned `git grep` process exits with a code other than 0 (matches) or 1 (no matches — deliberately treated as an empty result). Any other exit code means git itself failed: not inside a git repository (exit 128), a bad pattern (exit 2), or a broken git installation. The message includes git's stderr.

Solutions

  1. Ensure the search cwd is inside a git working tree (`git rev-parse --show-toplevel` in that directory); otherwise pick the rg/ag/grep provider instead.
  2. Fix the query pattern if regex mode is enabled.
  3. Run `git grep -n -e <query>` manually in the target cwd to read the exact stderr.
  4. Verify git is installed and the repository is not corrupt (`git status`).
Defensive patterns

Strategy: validation

Validate before calling

import { execSync } from "child_process";
function insideGitRepo(cwd: string): boolean {
  try { execSync("git rev-parse --is-inside-work-tree", { cwd, stdio: "ignore" }); return true; } catch { return false; }
}
// skip the git-grep provider when insideGitRepo(gitCwd) is false

Type guard

function isRepoCheck(r) { return r.exit_code === 0 || r.exit_code === 1; } // exit 128 = not a repo

Try / catch

try {
  results = await gitGrepProvider.search(query, opts);
} catch (e) {
  if (/exited with code 128/.test(String(e))) {
    results = await rgProvider.search(query, opts); // not a git repo — use another backend
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling live-grep with the git-grep provider when: (1) the resolved cwd (preferred cwd or active buffer dir, per gitCwdFor) is not inside a git repository, (2) the query is an invalid regex/POSIX pattern for git grep, or (3) git is not installed or the repo is corrupt.

Common situations: Opening a single file outside any repo and searching (monorepo edge the gitCwd fallback can't fix); searching with regex mode on and an invalid pattern; a bare/worktree layout where `git grep` is refused; missing git binary in PATH.

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


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/4cb116280d850d46. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor/plugins/live_grep.ts:570

    if (!gitCwd) return [] as GrepMatch[];
    const args = ["grep", "-n", "--column", "-I"];
    // Default git-grep is basic regex; use extended when regex is on, or
    // fixed-strings when it's off so the query is matched literally.
    args.push(regex === false ? "-F" : "-E");
    if (wholeWord) args.push("-w");
    if (includeIgnored) {
      // Widen beyond tracked files: include untracked, and stop
      // honouring the standard ignore files so `.gitignore`d content
      // is searched too.
      args.push("--untracked", "--no-exclude-standard");
    }
    args.push("-e", query);
    const r = await editor.spawnProcess("git", args, gitCwd);
    // git grep exits 1 when no matches — treat as empty, not error.
    if (r.exit_code === 0 || r.exit_code === 1) {
      return parseGrepOutput(r.stdout, maxResults, (msg) => editor.debug(msg)) as GrepMatch[];
    }
    throw new Error(`git grep exited with code ${r.exit_code}: ${r.stderr}`);
  },
});

registerProvider({
  name: "ack",
  priority: -3,
  // Note: ack/grep are kept at lower priority than ripgrep/ag/
  // git-grep because they're slower on large trees; the cycler
  // skips them automatically when a faster backend is available.
  isAvailable: async () => {
    try {
      const r = await editor.spawnProcess("ack", ["--version"], editor.getCwd());
      return r.exit_code === 0;
    } catch {
      return false;
    }
  },
  search: async (query, { cwd, maxResults, wholeWord, regex }) => {

View on GitHub (pinned to 67894ca546)