{"record":{"id":"de2864fa0ff5aef1","repo":"openai/codex-plugin-cc","slug":"git-is-not-installed-install-git-and-retry","errorCode":null,"errorMessage":"git is not installed. Install Git and retry.","messagePattern":"git is not installed\\. Install Git and retry\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/codex/scripts/lib/git.mjs","lineNumber":82,"sourceCode":"    }\n  }\n  return totalBytes;\n}\n\nfunction buildBranchComparison(cwd, baseRef) {\n  const mergeBase = gitChecked(cwd, [\"merge-base\", \"HEAD\", baseRef]).stdout.trim();\n  return {\n    mergeBase,\n    commitRange: `${mergeBase}..HEAD`,\n    reviewRange: `${baseRef}...HEAD`\n  };\n}\n\nexport function ensureGitRepository(cwd) {\n  const result = git(cwd, [\"rev-parse\", \"--show-toplevel\"]);\n  const errorCode = result.error && \"code\" in result.error ? result.error.code : null;\n  if (errorCode === \"ENOENT\") {\n    throw new Error(\"git is not installed. Install Git and retry.\");\n  }\n  if (result.status !== 0) {\n    throw new Error(\"This command must run inside a Git repository.\");\n  }\n  return result.stdout.trim();\n}\n\nexport function getRepoRoot(cwd) {\n  return gitChecked(cwd, [\"rev-parse\", \"--show-toplevel\"]).stdout.trim();\n}\n\nexport function detectDefaultBranch(cwd) {\n  const symbolic = git(cwd, [\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n  if (symbolic.status === 0) {\n    const remoteHead = symbolic.stdout.trim();\n    if (remoteHead.startsWith(\"refs/remotes/origin/\")) {\n      return remoteHead.replace(\"refs/remotes/origin/\", \"\");\n    }","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/openai/codex-plugin-cc/blob/db52e28f4d9ded852ab3942cea316258ae4ef346/plugins/codex/scripts/lib/git.mjs#L64-L100","documentation":"Thrown by ensureGitRepository when spawning 'git' fails with error.code === 'ENOENT', meaning the git executable was not found on PATH. The function runs git with shell:false via runCommand, so Node's spawn raises ENOENT when the binary is absent; the code maps that to an install hint.","triggerScenarios":"Calling ensureGitRepository(cwd) (directly or via resolveReviewTarget) on a system where git is not installed or not on the process PATH. The ENOENT comes from Node's child_process.spawn failing to locate the 'git' executable.","commonSituations":"Minimal container/CI image without git. A desktop where git is installed but PATH is not propagated to the agent's process. Windows without Git on PATH (or git.cmd not resolvable). A sandboxed environment that strips PATH.","solutions":["Install Git (apt-get install git, brew install git, or the official Windows installer).","Ensure the git executable directory is on PATH for the process running the agent.","On Windows, confirm 'git --version' works in the same shell; add Git's bin to PATH.","Restart the shell/agent after PATH changes so the new environment is picked up."],"exampleFix":"// before\nensureGitRepository(cwd) // throws ENOENT -> 'git is not installed'\n\n// after (shell setup)\n//   apt-get update && apt-get install -y git   # Linux\n//   brew install git                           # macOS\n//   # Windows: install Git for Windows, ensure C:\\Program Files\\Git\\cmd on PATH\nensureGitRepository(cwd)","handlingStrategy":"validation","validationCode":"import { execFileSync } from 'node:child_process';\n\nfunction gitAvailable() {\n  try {\n    execFileSync('git', ['--version'], { stdio: 'ignore', shell: false });\n    return true;\n  } catch {\n    return false;\n  }\n}\nif (!gitAvailable()) {\n  throw new Error('Git must be installed and on PATH');\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Install Git in all environments that run repo-relative commands (CI, containers).","Ensure the git bin dir is on PATH for the agent process.","On Windows, install Git for Windows and add its cmd dir to PATH.","Probe 'git --version' during onboarding/setup."],"tags":["git","dependency","install","environment"],"backgroundTag":null,"analyzedSha":"db52e28f4d9ded852ab3942cea316258ae4ef346","analyzedAt":"2026-08-13T05:13:20.855Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}