{"record":{"id":"56dc11802e251441","repo":"jdx/mise","slug":"failed-to-inspect-git-blob-oid","errorCode":null,"errorMessage":"failed to inspect Git blob {oid}","messagePattern":"failed to inspect Git blob (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/git.rs","lineNumber":836,"sourceCode":"            .stderr(Stdio::inherit())\n            .spawn()?;\n        let mut bytes = Vec::new();\n        // Keep the pipe open until Git has exited: dropping it before kill\n        // can make a large blob emit a spurious broken-pipe error on stderr.\n        let mut output = child\n            .stdout\n            .take()\n            .expect(\"stdout was piped\")\n            .take(prefix.len() as u64);\n        let read = output.read_to_end(&mut bytes);\n        let complete = bytes.len() == prefix.len();\n        if complete || read.is_err() {\n            let _ = child.kill();\n        }\n        let status = child.wait()?;\n        read?;\n        if !complete && !status.success() {\n            eyre::bail!(\"failed to inspect Git blob {oid}\");\n        }\n        Ok(bytes == prefix)\n    }\n\n    /// Runs the call and returns its full output without treating a non-zero\n    /// exit as an error, for commands whose status carries meaning.\n    pub(crate) fn output_unchecked(&self, call: PlumbingCall<'_>) -> Result<std::process::Output> {\n        let cmd = self.command(&call)?;\n        spawn_plumbing(cmd, call.stdin)\n    }\n\n    /// Runs the call with stdout and stderr inherited, for output that goes\n    /// straight to the terminal (a patch can be as large as a snapshot), and\n    /// returns its status without treating a non-zero exit as an error.\n    pub(crate) fn status_inherited(\n        &self,\n        call: PlumbingCall<'_>,\n    ) -> Result<std::process::ExitStatus> {","sourceCodeStart":818,"sourceCodeEnd":854,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/git.rs#L818-L854","documentation":"blob_starts_with streams `git cat-file blob <oid>` and reads only a prefix of the blob. If the read did not complete (prefix not fully read) and the git child process exited non-zero, mise cannot determine the blob's contents — typically because the object does not exist or the repository is corrupt — so it raises this error naming the oid.","triggerScenarios":"Calling Git::blob_starts_with(oid, prefix) where `git cat-file blob <oid>` exits non-zero (or fails to start reading) before the prefix is fully read: missing object, corrupt object store, or an unusable git directory.","commonSituations":"A fetched/shallow or pruned repository missing the blob oid; a partially cloned or interrupted git fetch leaving a dangling reference; the bare cache directory (e.g. ~/.cache/mise/git) deleted or corrupted mid-operation; disk errors or permissions on the git dir; git version incompatibilities writing unreadable objects.","solutions":["Delete the cached git directory for that repository (e.g. under ~/.cache/mise/git) and let mise re-clone it.","Run `git fsck` on the underlying repository/cache to diagnose corruption, then re-fetch.","Re-run the operation that triggered the fetch so the missing objects are downloaded.","Verify the git installation works (`git --version`, `git cat-file -e <oid>`) in the affected repo.","Check disk space and permissions on the cache/git directory."],"exampleFix":"# before: corrupted cached clone\n$ rm -rf ~/.cache/mise/git/github.com/<owner>/<repo>\n$ mise install  # re-clones and refetches objects\n// after: operation succeeds with a fresh clone","handlingStrategy":"try-catch","validationCode":"// before calling blob_starts_with\nconst ok = await run(`git -C ${repoDir} cat-file -e ${oid}`); // non-zero => object missing","typeGuard":null,"tryCatchPattern":"match repo.blob_starts_with(oid, prefix) {\n    Ok(startsWith) => /* proceed */,\n    Err(e) if e.to_string().contains(\"failed to inspect Git blob\") => {\n        // wipe the cached git dir for this repo and retry once after re-clone\n        fs::remove_dir_all(cache_dir)?;\n        let repo = Git::new(...)?; repo.blob_starts_with(oid, prefix)\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Avoid deleting or pruning the mise git cache directory while operations run","Keep adequate disk space and correct permissions on ~/.cache/mise/git","Re-run failed installs so missing objects are re-fetched","Run `git fsck` if the error repeats to detect store corruption"],"tags":["git","blob","corruption","cache"],"backgroundTag":"git-command-failed","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}