zed-industries/zed · error
invalid git oid byte length: expected {SHA1_BYTE_LENGTH} for
Error message
invalid git oid byte length: expected {SHA1_BYTE_LENGTH} for SHA-1 or {SHA256_BYTE_LENGTH} for SHA-256, got {len} What it means
Oid::from_bytes accepts only the two raw object-id byte lengths git uses: 20 bytes (SHA-1) or 32 bytes (SHA-256); anything else bails with the observed length. The bytes are then zero-padded into a fixed 32-byte array tagged with the detected format, so a wrong length cannot be guessed. This is the binary counterpart of the hex-length check in FromStr.
Source
Thrown at crates/git/src/git.rs:209
Self::Sha256 => SHA256_BYTE_LENGTH,
}
}
fn hex_len(self) -> usize {
match self {
Self::Sha1 => SHA1_HEX_LENGTH,
Self::Sha256 => SHA256_HEX_LENGTH,
}
}
}
impl Oid {
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
let format = match bytes.len() {
SHA1_BYTE_LENGTH => OidFormat::Sha1,
SHA256_BYTE_LENGTH => OidFormat::Sha256,
len => {
anyhow::bail!(
"invalid git oid byte length: expected {SHA1_BYTE_LENGTH} for SHA-1 or {SHA256_BYTE_LENGTH} for SHA-256, got {len}"
);
}
};
let mut oid_bytes = [0u8; SHA256_BYTE_LENGTH];
oid_bytes[..bytes.len()].copy_from_slice(bytes);
Ok(Self {
bytes: oid_bytes,
format,
})
}
#[cfg(any(test, feature = "test-support"))]
pub fn random(rng: &mut impl rand::Rng) -> Self {
let mut bytes = [0u8; SHA256_BYTE_LENGTH];
rng.fill(&mut bytes[..SHA1_BYTE_LENGTH]);
Self {View on GitHub (pinned to f4178619ac)
Solutions
- If the input is hex text, use Oid::from_str / str::parse instead of from_bytes
- If it is raw, ensure exactly 20 (SHA-1) or 32 (SHA-256) bytes — check slicing ranges and the source of the buffer
- Validate length at the boundary where external ids enter your code
Example fix
// before let oid = Oid::from_bytes(hex_oid.as_bytes())?; // 40 bytes of ASCII -> invalid git oid byte length ... got 40 // after let oid = Oid::from_str(hex_oid)?;
Defensive patterns
Strategy: type-guard
Validate before calling
if bytes.len() != 20 && bytes.len() != 32 {
return Err(format!("refusing to build Oid from {} bytes", bytes.len()));
} Type guard
fn is_valid_oid_byte_length(len: usize) -> bool {
matches!(len, 20 | 32)
} Try / catch
let oid = match Oid::from_bytes(bytes) {
Ok(oid) => oid,
Err(e) if e.to_string().contains("oid byte length") => Oid::from_str(&String::from_utf8_lossy(bytes))?,
Err(e) => return Err(e),
}; Prevention
- Use from_str for hex input and from_bytes only for decoded raw ids
- Assert buffer lengths at the boundary where external ids enter
When it happens
Trigger: Calling Oid::from_bytes with hex-string bytes (40 or 64 ASCII characters), a truncated hash, a 20-byte buffer off by slicing, or object ids from a non-git source with arbitrary length.
Common situations: Accidentally passing a hex oid's UTF-8 bytes instead of decoded bytes, slicing an oid buffer with the wrong range, or handling shortened/abbreviated ids through the byte API.
Related errors
- invalid git oid hex length: expected 1..={SHA1_HEX_LENGTH} f
- extension dir {} is not an absolute path
- grammar directory '{}' already exists, but is not a git clon
- failed to run `git init` in directory '{}'
- path dataset requires data_dir
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/f839b808efce588c.
Report an issue: GitHub.