zed-industries/zed · error
invalid git oid hex length: expected 1..={SHA1_HEX_LENGTH} f
Error message
invalid git oid hex length: expected 1..={SHA1_HEX_LENGTH} for SHA-1 or {SHA256_HEX_LENGTH} for SHA-256, got {len} What it means
Oid::from_str classifies the hex string purely by length: 1..=40 hex chars are treated as an abbreviated-or-full SHA-1 oid, exactly 64 as SHA-256, and anything else bails with the observed length. There is deliberately no middle ground — 41-63 chars, 0 chars (empty string), or >64 are all rejected before any hex-digit decoding happens.
Source
Thrown at crates/git/src/git.rs:290
}
impl TryFrom<&str> for Oid {
type Error = anyhow::Error;
fn try_from(value: &str) -> std::result::Result<Self, Self::Error> {
Oid::from_str(value)
}
}
impl FromStr for Oid {
type Err = anyhow::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let format = match s.len() {
1..=SHA1_HEX_LENGTH => OidFormat::Sha1,
SHA256_HEX_LENGTH => OidFormat::Sha256,
len => {
anyhow::bail!(
"invalid git oid hex length: expected 1..={SHA1_HEX_LENGTH} for SHA-1 or {SHA256_HEX_LENGTH} for SHA-256, got {len}"
);
}
};
let mut bytes = [0u8; SHA256_BYTE_LENGTH];
for (index, byte) in s.bytes().enumerate() {
let digit = decode_hex_digit(byte)
.ok_or_else(|| anyhow::anyhow!("invalid hex digit at byte {index} for git oid"))?;
if index % 2 == 0 {
bytes[index / 2] = digit << 4;
} else {
bytes[index / 2] |= digit;
}
}
Ok(Self { bytes, format })
}View on GitHub (pinned to f4178619ac)
Solutions
- Trim whitespace/newlines from the string before parsing
- Check the length: use a full 40-char SHA-1, an abbreviation of 1–40 chars, or a full 64-char SHA-256
- Fix the upstream splitting/format string (e.g. %x00 delimiters) so oids arrive clean
Example fix
// before let oid: Oid = line_with_trailing_newline.parse()?; // len 41 -> invalid git oid hex length // after let oid = Oid::from_str(line.trim())?;
Defensive patterns
Strategy: type-guard
Validate before calling
let s = s.trim();
if !(1..=40).contains(&s.len()) && s.len() != 64 {
return Err(format!("oid string has invalid length {}", s.len()));
} Type guard
fn is_valid_oid_hex(s: &str) -> bool {
let len = s.len();
((1..=40).contains(&len) || len == 64) && s.bytes().all(|b| b.is_ascii_hexdigit())
} Try / catch
let oid = match Oid::from_str(raw) {
Ok(oid) => oid,
Err(e) if e.to_string().contains("hex length") => Oid::from_str(raw.trim())?,
Err(e) => return Err(e),
}; Prevention
- Trim every oid parsed from split output; delimiters and newlines inflate the length
- Remember 41–63 chars are always invalid — no abbreviation exists in that range
When it happens
Trigger: Parsing an oid string with 41–63 hex characters (e.g. a SHA-1 with appended characters or a truncated SHA-256), an empty string, a 65+ char string, or text with whitespace/newlines inflating the length.
Common situations: Splitting git output on the wrong delimiter leaving trailing characters, concatenated oids not re-split, user-pasted revs with spaces or newlines, or copying 64+ char strings from non-git tools.
Related errors
- invalid git oid byte length: expected {SHA1_BYTE_LENGTH} for
- unsupported raw diff status {status}
- raw diff is missing the status
- unexpected git-show output for {commit:?}: {output:?}
- extension dir {} is not an absolute path
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/9f9c2c8390bee638.
Report an issue: GitHub.