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

  1. If the input is hex text, use Oid::from_str / str::parse instead of from_bytes
  2. If it is raw, ensure exactly 20 (SHA-1) or 32 (SHA-256) bytes — check slicing ranges and the source of the buffer
  3. 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

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


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/f839b808efce588c. Report an issue: GitHub.