{"record":{"id":"816240c3de28a394","repo":"zed-industries/zed","slug":"invalid-cat-file-header-header-line","errorCode":null,"errorMessage":"invalid cat-file header: {header_line}","messagePattern":"invalid cat-file header: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/git/src/repository.rs","lineNumber":1813,"sourceCode":"                let output = std::str::from_utf8(&output.stdout)?;\n                let shas = output\n                    .lines()\n                    .map(|line| {\n                        if line.ends_with(\"missing\") {\n                            None\n                        } else {\n                            Some(line.to_string())\n                        }\n                    })\n                    .collect::<Vec<_>>();\n\n                if shas.len() != revs.len() {\n                    // In an octopus merge, git cat-file still only outputs the first sha from MERGE_HEAD.\n                    bail!(\"unexpected number of shas\")\n                }\n\n                Ok(shas)\n            })\n            .boxed()\n    }\n\n    fn load_revisions(\n        &self,\n        revisions: Vec<String>,\n    ) -> BoxFuture<'_, Result<Vec<Option<Vec<u8>>>>> {\n        let git = self.git_binary();\n        self.executor\n            .spawn(async move {\n                if revisions.is_empty() {\n                    return Ok(Vec::new());\n                }\n                if let Some(revision) = revisions.iter().find(|revision| revision.contains('\\n')) {\n                    anyhow::bail!(\n                        \"revision spec {revision:?} contains a newline and cannot be passed to git cat-file --batch\"\n                    );\n                }","sourceCodeStart":1795,"sourceCodeEnd":1831,"githubUrl":"https://github.com/zed-industries/zed/blob/5a9b9558db01a6b906cec2fb70a797affdc58cdd/crates/git/src/repository.rs#L1795-L1831","documentation":"load_revisions() parses the stdout of `git cat-file --batch`, where every response starts with a header line of the form `<oid> <type> <size>`. When a header line does not match any expected shape, this error is raised with the raw line included, and the whole batch fails.","triggerScenarios":"A revision in the batch does not resolve, so git answers a short line (e.g. `<spec> missing`) instead of a header; or the batch stream is desynchronized because a previous response body was not fully consumed (wrong size read); or an unexpected git version emits nonstandard batch output.","commonSituations":"Passing short SHAs, tags, or expressions that do not exist in the local object store; shallow or partial clones missing objects; a concurrent `git gc` pruning objects between listing and loading; earlier parsing bugs that left the stdout stream offset.","solutions":["Check the header line printed in the message: if it ends with `missing`, the revision does not exist locally — fetch or drop it before batching.","Resolve/verify every revision with `git rev-parse --verify` (and treat missing ones as `None`) before the batch call.","If the line looks like garbage rather than a real git answer, suspect stream desync: ensure no other consumer reads from the cat-file process stdout.","Upgrade the git binary if its batch output is nonstandard."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"for spec in &revisions {\n    git.run(&[\"rev-parse\", \"--verify\", &format!(\"{spec}^{{object}}\"))]).await?;\n}","typeGuard":null,"tryCatchPattern":"match repo.load_revisions(revisions).await {\n    Err(e) if e.to_string().contains(\"invalid cat-file header\") => {\n        // one revision likely does not resolve: re-check each with rev-parse and retry without it\n    }\n    other => other?,\n}","preventionTips":["Resolve every revision and drop unresolvable ones before batch loading.","Treat missing objects (shallow clones, pruned history) as `None` results rather than batch failures.","Keep a single owner for the cat-file process stdout so the stream cannot desync."],"tags":["git","cat-file","parsing","batch-protocol"],"backgroundTag":"git-command-output-parsing","analyzedSha":"5a9b9558db01a6b906cec2fb70a797affdc58cdd","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}