diff --git a/packages/coding-agent/src/utils/git.ts b/packages/coding-agent/src/utils/git.ts index 22fc38183..bcfbbb4da 100644 --- a/packages/coding-agent/src/utils/git.ts +++ b/packages/coding-agent/src/utils/git.ts @@ -442,7 +442,14 @@ async function git(cwd: string, args: readonly string[], options: CommandOptions windowsHide: true, }); } catch (err) { - if (isEnoent(err)) return { exitCode: GIT_SPAWN_ENOENT_EXIT_CODE, stdout: "", stderr: "git is not installed." }; + if (isEnoent(err)) { + // A deleted/nonexistent cwd also surfaces as a spawn ENOENT; only blame + // the binary when the working directory actually exists. + const stderr = fs.existsSync(cwd) + ? "git is not installed." + : `working directory does not exist: ${cwd}`; + return { exitCode: GIT_SPAWN_ENOENT_EXIT_CODE, stdout: "", stderr }; + } throw err; } diff --git a/packages/coding-agent/test/git-missing-binary.test.ts b/packages/coding-agent/test/git-missing-binary.test.ts index 57e2d4c73..e37139bb1 100644 --- a/packages/coding-agent/test/git-missing-binary.test.ts +++ b/packages/coding-agent/test/git-missing-binary.test.ts @@ -33,6 +33,15 @@ describe("git helpers with git binary absent (#6169)", () => { await expect(git.diff.has("/")).rejects.toThrow("git is not installed."); }); + it("does not blame the git binary when the cwd is what is missing", async () => { + vi.spyOn(Bun, "spawn").mockImplementation(throwSpawnEnoent); + // A deleted cwd also makes spawn throw ENOENT; the error must name the + // directory, not falsely claim git is uninstalled. + await expect(git.diff.has("/nonexistent-omp-eval-dir")).rejects.toThrow( + "working directory does not exist: /nonexistent-omp-eval-dir", + ); + }); + it("repo.root degrades to null instead of throwing ENOENT", async () => { vi.spyOn(Bun, "spawn").mockImplementation(throwSpawnEnoent); expect(await git.repo.root("/")).toBeNull();