{"record":{"id":"9c42c97bef214845","repo":"vercel/turborepo","slug":"which-git-produced-an-invalid-absolute-path","errorCode":null,"errorMessage":"which git produced an invalid absolute path {}","messagePattern":"which git produced an invalid absolute path (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/turborepo-scm/src/lib.rs","lineNumber":315,"sourceCode":"        // If which produces an invalid absolute path, it's not an execution error, it's\n        // a programming error. We expect it to always give us an absolute path\n        // if it gives us any path. If that's not the case, we should crash.\n        let bin = Self::find_bin()?;\n        let root =\n            find_git_root(path_in_repo).map_err(|e| GitError::Root(path_in_repo.to_owned(), e))?;\n        Ok(Self {\n            root,\n            bin,\n            attrs: OnceLock::new(),\n            github_actions_remote_base_ref_fallback: false,\n            slowest_files: None,\n        })\n    }\n\n    pub fn find_bin() -> Result<AbsoluteSystemPathBuf, which::Error> {\n        which::which(\"git\").map(|path| {\n            AbsoluteSystemPathBuf::try_from(path.as_path()).unwrap_or_else(|_| {\n                panic!(\n                    \"which git produced an invalid absolute path {}\",\n                    path.display()\n                )\n            })\n        })\n    }\n}\n\nfn find_git_root(turbo_root: &AbsoluteSystemPath) -> Result<AbsoluteSystemPathBuf, Error> {\n    let rev_parse = Command::new(\"git\")\n        .args([\"rev-parse\", \"--show-cdup\"])\n        .current_dir(turbo_root)\n        .output()?;\n    if !rev_parse.status.success() {\n        let stderr = String::from_utf8_lossy(&rev_parse.stderr);\n        return Err(Error::git_error(format!(\n            \"git rev-parse --show-cdup error: {stderr}\"\n        )));","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/vercel/turborepo/blob/7fe373bc270adb30db3c184c55069f77feb1a6d6/crates/turborepo-scm/src/lib.rs#L297-L333","documentation":"Scm::find_bin() locates the git executable with the which crate and converts the discovered path into an AbsoluteSystemPathBuf. which guarantees an absolute path, so the conversion can only fail on non-UTF-8 bytes — the panic fires when the resolved git binary lives under a path containing invalid UTF-8.","triggerScenarios":"A PATH entry with non-UTF-8 bytes (legacy ANSI-encoded directory or username) that resolves git first; a git shim/wrapper installed in an oddly-encoded location on Windows.","commonSituations":"Windows user profiles with non-ASCII or legacy-encoded names where the PATH byte sequence is not valid UTF-8; corporate wrapper scripts in unusual directories; WOS/WSL boundary quirks mixing encodings.","solutions":["Check what actually resolves: `where git` (Windows) or `which git` — the printed path should be plain ASCII","Reinstall git to a default ASCII location (e.g. C:\\Program Files\\Git) and make sure that PATH entry wins","Fix or remove the non-UTF-8 PATH entry (often caused by an encoded username — recreate the directory in ASCII)","As a workaround, set PATH explicitly in the shell/task before running turbo"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Resolve git once and verify the path is ASCII/UTF-8 before turbo runs\nuse std::process::Command;\nlet out = Command::new(\"where\") // Windows; use \"which -a\" on Unix\n    .arg(\"git\")\n    .output()?;\nlet paths = String::from_utf8_lossy(&out.stdout);\nif paths.contains('\\uFFFD') {\n    return Err(\"git resolved to a non-UTF-8 path — fix PATH\".into());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Install git in a default ASCII-only location and put that PATH entry first","Avoid non-ASCII/legacy-encoded usernames and directories in PATH on Windows","In CI images, set PATH explicitly to known-ASCII tool directories before running turbo"],"tags":["git","which","utf8","path","windows","panic"],"backgroundTag":"non-utf8-file-path","analyzedSha":"7fe373bc270adb30db3c184c55069f77feb1a6d6","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}