cross-rs/cross · error

commit hash must be at least

Error message

commit hash must be at least {LENGTH} characters long

What it means

`short_commit_hash` truncates a commit hash to the 9-character short form used by Cargo (rust-lang/cargo#10579). It panics when the input string is shorter than 9 characters, since `str::get(..9)` returns None. This is a guard against garbage/short identifiers being treated as commit hashes.

Solutions

  1. Verify the input is a full commit hash: run `rustc -vV` and check the `commit-hash:` line has at least 9 hex characters.
  2. Validate length before calling: `assert!(hash.len() >= 9)` or return a proper error instead of panicking.
  3. If the version string is hand-assembled, include the full commit hash rather than an abbreviated one.

Example fix

// before
let short = short_commit_hash("abc123"); // panics: only 6 chars
// after
let hash = "abc123def";
assert!(hash.len() >= 9);
let short = short_commit_hash(hash); // "abc123def"
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_commit_hash(hash: &str) -> bool { hash.len() >= 9 && hash.chars().all(|c| c.is_ascii_hexdigit()) }
if !is_valid_commit_hash(input) { return Err(...); }
let short = short_commit_hash(input);

Type guard

fn as_full_commit_hash(s: &str) -> Option<&str> { (s.len() >= 9 && s.chars().all(|c| c.is_ascii_hexdigit())).then_some(s) }

Prevention

When it happens

Trigger: Calling `short_commit_hash` (directly or via `commit_hash` or `hash_from_version_string`) with a string of fewer than 9 ASCII characters, e.g. a version metadata field like "abc123".

Common situations: A rustc version string whose commit hash portion was truncated or hand-edited, a custom/patched toolchain reporting a short or missing commit hash in its `-v` output, or parsing an incorrectly formatted version string.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of cross-rs/cross@8c1a8aa4b6 (2026-09-13). Data as JSON: /api/errors/41961ad7ccfd001d. Report an issue: GitHub.

Appendix: source

Thrown at src/rustc.rs:54

    fn needs_interpreter(&self) -> bool {
        self.semver < Version::new(1, 19, 0)
    }

    fn commit_hash(&self) -> String {
        self.commit_hash.as_ref().map_or_else(
            || hash_from_version_string(&self.short_version_string, 2),
            |x| short_commit_hash(x),
        )
    }
}

fn short_commit_hash(hash: &str) -> String {
    // short version hashes are always 9 digits
    //  https://github.com/rust-lang/cargo/pull/10579
    const LENGTH: usize = 9;

    hash.get(..LENGTH)
        .unwrap_or_else(|| panic!("commit hash must be at least {LENGTH} characters long"))
        .to_owned()
}

#[must_use]
pub fn hash_from_version_string(version: &str, index: usize) -> String {
    let is_hash = |x: &str| x.chars().all(|c| c.is_ascii_hexdigit());
    let is_date = |x: &str| x.chars().all(|c| matches!(c, '-' | '0'..='9'));

    // the version can be one of two forms:
    //   multirust channel string: `"1.61.0 (fe5b13d68 2022-05-18)"`
    //   short version string: `"rustc 1.61.0 (fe5b13d68 2022-05-18)"`
    // want to extract the commit hash if we can, if not, just hash the string.
    if let Some((commit, date)) = version
        .splitn(index + 1, ' ')
        .nth(index)
        .and_then(|meta| meta.strip_prefix('('))
        .and_then(|meta| meta.strip_suffix(')'))
        .and_then(|meta| meta.split_once(' '))

View on GitHub (pinned to 8c1a8aa4b6)