{"record":{"id":"cd8c22e95158fa72","repo":"Hmbown/CodeWhale","slug":"git-not-found-on-path-cd8c22","errorCode":null,"errorMessage":"git not found on PATH","messagePattern":"git not found on PATH","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/snapshot/repo.rs","lineNumber":794,"sourceCode":"                &[\"update-ref\", \"HEAD\", &final_sha],\n            )?;\n            if !up.status.success() {\n                return Err(io_other(format!(\n                    \"update-ref HEAD failed: {}\",\n                    String::from_utf8_lossy(&up.stderr).trim()\n                )));\n            }\n        }\n        Ok(())\n    }\n\n    /// Run a `commit-tree` invocation with the author/committer dates pinned\n    /// to `timestamp` (Unix seconds), so a rebuilt survivor keeps its real\n    /// age instead of stamping \"now\".\n    fn commit_tree_preserving_date(&self, args: &[&str], timestamp: i64) -> io::Result<String> {\n        let date = format!(\"{timestamp} +0000\");\n        let out = crate::dependencies::Git::command()\n            .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, \"git not found on PATH\"))?\n            .arg(\"--git-dir\")\n            .arg(&self.git_dir)\n            .arg(\"--work-tree\")\n            .arg(&self.work_tree)\n            .env(\"GIT_AUTHOR_DATE\", &date)\n            .env(\"GIT_COMMITTER_DATE\", &date)\n            .args(args)\n            .output()?;\n        if !out.status.success() {\n            return Err(io_other(format!(\n                \"commit-tree failed: {}\",\n                String::from_utf8_lossy(&out.stderr).trim()\n            )));\n        }\n        Ok(String::from_utf8_lossy(&out.stdout).trim().to_string())\n    }\n\n    /// Keep only the latest `max_count` snapshots, dropping older ones.","sourceCodeStart":776,"sourceCodeEnd":812,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/snapshot/repo.rs#L776-L812","documentation":"NotFound error raised when crate::dependencies::Git::command() cannot resolve the git executable on PATH and the snapshot repo then needs to run commit-tree (commit_tree_preserving_date, used during history rebuild/prune to keep survivor commits' original dates). Every snapshot git invocation goes through this dependency shim, so a missing git binary disables snapshots entirely.","triggerScenarios":"Snapshot pruning/rebuild runs commit-tree while the git executable is not resolvable from the process PATH — git not installed, or the app launched from an environment whose PATH lacks git (GUI launchers, service contexts, minimal containers).","commonSituations":"macOS launch from Finder/Dock where PATH is the minimal system default; systemd/service or cron launches with sanitized env; distrobox/Nix shells without git in scope; slim Docker images without git installed.","solutions":["Install git and confirm `git --version` works in the same environment the app runs in","If launching from a GUI, start the app from a login shell or configure the launcher to inherit a PATH that includes git (/usr/bin, /opt/homebrew/bin, ~/.nix-profile/bin)","In containers/images, add git to the image rather than relying on runtime mounting"],"exampleFix":"# before\n$ open -a Codewhale        # PATH=/usr/bin:/bin:/usr/sbin:/sbin -> Err: git not found on PATH\n\n# after\n$ /opt/homebrew/bin/git --version   # verify location\n$ codewhale                        # launched from login shell with git on PATH","handlingStrategy":"validation","validationCode":"// Verify git is resolvable in the app's own environment before enabling snapshots.\nif which::which(\"git\").is_err() {\n    eprintln!(\"snapshots require git on PATH\");\n    std::process::exit(2);\n}","typeGuard":"fn is_git_missing(e: &std::io::Error) -> bool {\n    e.kind() == std::io::ErrorKind::NotFound && e.to_string().contains(\"git\")\n}","tryCatchPattern":"match snapshots::Repo::open(&ws) {\n    Ok(r) => Ok(r),\n    Err(e) if is_git_missing(&e) => disable_snapshots_with_notice(\"install git and restart\"),\n    Err(e) => Err(e),\n}","preventionTips":["Check `which git` inside the exact launch context (service unit, launcher plist), not just your shell","Bake git into container images rather than assuming the runtime provides it","Fail fast at startup when a feature that needs git is enabled"],"tags":["git","snapshots","environment","path","rust"],"backgroundTag":"git-executable-not-found","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}