GitoxideLabs/gitoxide · error · anyhow::Error

Binary data at cannot be diffed

Error message

Binary data at {path} cannot be diffed

What it means

Thrown by `display_object` in `gix repo cat` when diffing a blob whose content is binary (detected during diff resource cache preparation), so no text diff data is available to write out. Only text data can be produced for `BlobFormat::Diff` output.

Solutions

  1. Use the plain blob format instead of diff, e.g. `gix repo cat <blob>` without the diff option, to dump raw bytes
  2. Configure a text conversion (gitattributes `diff` driver / filter) if the binary has a textual representation
  3. Check the blob content type first (`file <path>` or `gix repo cat <blob> | file -`) before requesting a diff

Example fix

// before
gix repo cat image.png --format diff
// after
gix repo cat image.png  # raw output, no diff
Defensive patterns

Strategy: fallback

Validate before calling

// cheap binary sniff before requesting a diff
fn looks_binary(bytes: &[u8]) -> bool {
    bytes.iter().take(8000).any(|&b| b == 0)
}

Type guard

fn diffable(data: Option<&[u8]>) -> bool {
    data.is_some() && !data.unwrap().iter().take(8000).any(|&b| b == 0)
}

Try / catch

match cat_diff(blob) {
    Err(e) if e.to_string().contains("cannot be diffed") => {
        // fall back to raw blob output
        out.write_all(&blob.object()?.data)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running `gix repo cat <blob> --format diff` (or DiffOrGit resolved to Diff) where the blob's bytes are classified as binary (contains NUL or fails text detection) by the diff cache.

Common situations: Trying to diff compiled artifacts, images, PNG/JPEG files, or any NUL-containing files stored in the repo; viewing old binary blobs in history.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/5a2008305eab6212. Report an issue: GitHub.

Appendix: source

Thrown at gitoxide-core/src/repository/cat.rs:51

                        &object.data,
                        path,
                        &mut |_path, attrs| {
                            let _ = platform.matching_attributes(attrs);
                        },
                        to_worktree::Options {
                            can_delay: Delay::Forbid,
                            unknown_encoding: to_worktree::UnknownEncoding::Fail,
                        },
                    )?;
                    std::io::copy(&mut converted, &mut out)?;
                }
                (BlobFormat::Diff | BlobFormat::DiffOrGit, cache) => {
                    cache.set_resource(id.detach(), mode.kind(), path, ResourceKind::OldOrSource, &repo.objects)?;
                    let resource = cache.resource(ResourceKind::OldOrSource).expect("just set");
                    let data = resource
                        .data
                        .as_slice()
                        .ok_or_else(|| anyhow!("Binary data at {path} cannot be diffed"))?;
                    out.write_all(data)?;
                }
            }
        }
        _ => out.write_all(&id.object()?.data)?,
    }
    Ok(())
}

pub(super) mod function {
    use crate::repository::revision::resolve::TreeMode;

    pub fn cat(repo: gix::Repository, revspec: &str, out: impl std::io::Write) -> anyhow::Result<()> {
        super::display_object(&repo, repo.rev_parse(revspec)?, TreeMode::Pretty, None, out)?;
        Ok(())
    }
}

View on GitHub (pinned to e73179060b)