rust-lang/cargo · error · anyhow::Error

expect run ID in format `20060724T012128000Z-<16-char-hex>`,

Error message

expect run ID in format `20060724T012128000Z-<16-char-hex>`, got `{s}`

What it means

RunId::from_str parses cargo run IDs of the form `<timestamp>-<16-hex-hash>` (e.g. `20060724T012128000Z-b0fd440798ab3cfb`). It splits on the last `-`; if there is no `-` at all (rsplit_once returns None) it bails with this message. The timestamp must match `%Y%m%dT%H%M%S%3fZ` and the hash must be exactly 16 ASCII hex digits.

Source

Thrown at src/util/logger.rs:201

    }
}

impl std::fmt::Display for RunId {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let hash = &self.hash;
        let timestamp = self.timestamp.strftime(Self::FORMAT);
        write!(f, "{timestamp}-{hash}")
    }
}

impl std::str::FromStr for RunId {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let msg =
            || format!("expect run ID in format `20060724T012128000Z-<16-char-hex>`, got `{s}`");
        let Some((timestamp, hash)) = s.rsplit_once('-') else {
            anyhow::bail!(msg());
        };

        if hash.len() != 16 || !hash.chars().all(|c| c.is_ascii_hexdigit()) {
            anyhow::bail!(msg());
        }
        let timestamp = jiff::civil::DateTime::strptime(Self::FORMAT, timestamp)
            .and_then(|dt| dt.to_zoned(jiff::tz::TimeZone::UTC))
            .map(|zoned| zoned.timestamp())
            .with_context(msg)?;

        Ok(RunId {
            timestamp,
            hash: hash.into(),
        })
    }
}

#[cfg(test)]

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Ensure the string has the form `<UTC-timestamp>-<16-hex>` with a single trailing hyphen-separated hash.
  2. Generate IDs from RunId::new and Display rather than hand-building strings.
  3. If reading from a file/env var, validate the shape before parsing.

Example fix

// before
let id: RunId = "abc123".parse()?; // no '-'

// after
let id: RunId = "20060724T012128000Z-b0fd440798ab3cfb".parse()?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_run_id_shape(s: &str) -> bool {
    s.rsplit_once('-').is_some()
}
// complements the hash check below

Type guard

fn run_id_has_separator(s: &str) -> bool { s.contains('-') }

Try / catch

match s.parse::<RunId>() {
    Err(e) if e.to_string().starts_with("expect run ID") => {
        eprintln!("run ID must be `<timestamp>-<16-hex>`; got {s:?}");
        return Err(e);
    }
    r => r,
}

Prevention

When it happens

Trigger: Parsing a run ID string that contains no `-` separator, e.g. a bare timestamp, a UUID, a git SHA, or any string without a hyphen, via RunId::from_str (e.g. reading a stale/foreign `CARGO_RUN_ID` or a log filename).

Common situations: A tooling script reads a directory name or env var expecting a cargo run ID but gets an unrelated identifier; a stale cache file from an older cargo format; manually constructing a run-id-like string and getting the format wrong.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/f2b25c2535b02236.json. Report an issue: GitHub.