rust-lang/cargo · error
expect run ID in format…
Error message
expect run ID in format `20060724T012128000Z-<16-char-hex>`, got `{s}` What it means
RunId::from_str expects the form `<timestamp>-<16-hex>`, e.g. `20060724T012128000Z-0123456789abcdef`. The first failure point is rsplit_once('-') returning None — the input contains no '-' separator at all, so it cannot be split into timestamp and hash.
Solutions
- Regenerate the run id by letting Cargo produce it (it always emits the canonical form).
- Ensure the value contains exactly one '-' separating a jiff-parseable timestamp from a 16-char hex suffix.
Example fix
# before # CARGO_LOG_RUN_ID=20060724T012128000Z # after # CARGO_LOG_RUN_ID=20060724T012128000Z-0123456789abcdef
Defensive patterns
Strategy: validation
Validate before calling
fn run_id_has_separator(s: &str) -> Result<(), String> {
if s.rsplit_once('-').is_none() {
return Err(format!("run id `{s}` missing '-' separator; expected <timestamp>-<16-hex>"));
}
Ok(())
} Type guard
fn run_id_shape_ok(s: &str) -> bool {
s.rsplit_once('-').is_some()
} Prevention
- Never truncate CARGO_LOG_RUN_ID; copy the full id cargo emits.
- Validate the id shape before exporting it in CI matrices.
When it happens
Trigger: Parsing a CARGO_LOG_RUN_ID (or equivalent) value that has no '-' separator, e.g. a bare timestamp, a bare hash, or a totally different string.
Common situations: Env var truncated by a shell quoting bug; a hand-typed run id; a tool writing only part of the id.
Related errors
- invalid url ` `: cannot-be-a-base-URLs are not supported
- sparse registry url must end in a slash `/
- Cannot specify both 'bin' and 'bin
- $CARGO not set
- config.json not found
AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11).
Data as JSON: /api/errors/f2b25c2535b02236.
Report an issue: GitHub.
Appendix: 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 eb98b54bc9)