zed-industries/zed · error
invalid cat-file header: {header_line}
Error message
invalid cat-file header: {header_line} What it means
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.
Source
Thrown at crates/git/src/repository.rs:1813
let output = std::str::from_utf8(&output.stdout)?;
let shas = output
.lines()
.map(|line| {
if line.ends_with("missing") {
None
} else {
Some(line.to_string())
}
})
.collect::<Vec<_>>();
if shas.len() != revs.len() {
// In an octopus merge, git cat-file still only outputs the first sha from MERGE_HEAD.
bail!("unexpected number of shas")
}
Ok(shas)
})
.boxed()
}
fn load_revisions(
&self,
revisions: Vec<String>,
) -> BoxFuture<'_, Result<Vec<Option<Vec<u8>>>>> {
let git = self.git_binary();
self.executor
.spawn(async move {
if revisions.is_empty() {
return Ok(Vec::new());
}
if let Some(revision) = revisions.iter().find(|revision| revision.contains('\n')) {
anyhow::bail!(
"revision spec {revision:?} contains a newline and cannot be passed to git cat-file --batch"
);
}View on GitHub (pinned to 5a9b9558db)
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.
Defensive patterns
Strategy: try-catch
Validate before calling
for spec in &revisions {
git.run(&["rev-parse", "--verify", &format!("{spec}^{{object}}"))]).await?;
} Try / catch
match repo.load_revisions(revisions).await {
Err(e) if e.to_string().contains("invalid cat-file header") => {
// one revision likely does not resolve: re-check each with rev-parse and retry without it
}
other => other?,
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid status code: {byte}
- Invalid unmerged status code: {byte}
- unexpected number of shas
- revision spec {revision:?} contains a newline and cannot be
- object not found: {}
AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20).
Data as JSON: /api/errors/816240c3de28a394.
Report an issue: GitHub.