spacedriveapp/spacedrive · error · anyhow::Error
Invalid time format: {}
Error message
Invalid time format: {} What it means
Thrown by parse_time_filter() (used for --since on 'sd sync metrics') when the string is not a relative '<N> <unit> ago' duration and also fails both absolute formats tried: RFC 3339 (DateTime::parse_from_rfc3339) and '%Y-%m-%d %H:%M:%S'. Note that a string ending in ' ago' is routed to parse_duration() instead and produces that function's errors, not this one.
Source
Thrown at apps/cli/src/domains/sync/mod.rs:149
}
}
fn parse_time_filter(time_str: &str) -> Result<DateTime<Utc>> {
// Try parsing as relative time first
if time_str.ends_with(" ago") {
let duration_str = &time_str[..time_str.len() - 4];
let duration = parse_duration(duration_str)?;
Ok(Utc::now() - duration)
} else {
// Try parsing as absolute time
DateTime::parse_from_rfc3339(time_str)
.map(|dt| dt.with_timezone(&Utc))
.or_else(|_| {
// Try common formats
DateTime::parse_from_str(time_str, "%Y-%m-%d %H:%M:%S")
.map(|dt| dt.with_timezone(&Utc))
})
.map_err(|_| anyhow::anyhow!("Invalid time format: {}", time_str))
}
}
fn parse_duration(duration_str: &str) -> Result<chrono::Duration> {
let parts: Vec<&str> = duration_str.split_whitespace().collect();
if parts.len() != 2 {
return Err(anyhow::anyhow!("Invalid duration format: {}", duration_str));
}
let value: i64 = parts[0]
.parse()
.map_err(|_| anyhow::anyhow!("Invalid number: {}", parts[0]))?;
let unit = parts[1].to_lowercase();
let seconds = match unit.as_str() {
"second" | "seconds" | "sec" | "s" => value,
"minute" | "minutes" | "min" | "m" => value * 60,
"hour" | "hours" | "h" => value * 3600,View on GitHub (pinned to 6dfeccf211)
Solutions
- Use RFC 3339: --since 2024-06-01T12:00:00Z
- Or 'YYYY-MM-DD HH:MM:SS': --since '2024-06-01 12:00:00' (quote it)
- Or a relative duration: --since '30 minutes ago', '2 hours ago', '7 days ago'
- Double-check for stray characters, missing seconds, or a date-only string
Example fix
// accepted inputs // RFC 3339: 2024-06-01T12:00:00Z // common format: "2024-06-01 12:00:00" // relative: "30 minutes ago" // before (fails): sd sync metrics --since 2024-06-01 // after: sd sync metrics --since '2024-06-01 00:00:00'
Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_time_filter(s: &str) -> bool {
if s.ends_with(" ago") {
let d = &s[..s.len() - 4];
let mut it = d.split_whitespace();
matches!((it.next(), it.next(), it.next()), (Some(n), Some(_), None))
&& n.parse::<i64>().is_ok()
} else {
chrono::DateTime::parse_from_rfc3339(s).is_ok()
|| chrono::DateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S").is_ok()
}
}
if !is_valid_time_filter(&since_str) {
eprintln!("--since accepts RFC 3339, 'YYYY-MM-DD HH:MM:SS', or '<N> <unit> ago'");
} Type guard
fn is_valid_time_filter(s: &str) -> bool {
if s.ends_with(" ago") {
let d = &s[..s.len() - 4];
let mut it = d.split_whitespace();
matches!((it.next(), it.next(), it.next()), (Some(n), Some(_), None))
&& n.parse::<i64>().is_ok()
} else {
chrono::DateTime::parse_from_rfc3339(s).is_ok()
|| chrono::DateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S").is_ok()
}
} Try / catch
match parse_time_filter(&since_str) {
Ok(t) => t,
Err(e) if e.to_string().starts_with("Invalid time format") => {
eprintln!("Supported: RFC 3339, 'YYYY-MM-DD HH:MM:SS', or e.g. '30 minutes ago'");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Standardize on RFC 3339 timestamps in scripts - they always parse
- Quote --since values in the shell to protect spaces
- Remember date-only strings ('2024-06-01') are NOT accepted; add a time component
When it happens
Trigger: Passing --since 2024-01-01 (date only, no time), --since '01/02/2024', --since 'yesterday', or any timestamp with a format outside the two accepted ones.
Common situations: Users assume natural-language dates or locale formats (MM/DD/YYYY) work; ISO date without time component; timezone-suffix variants like '+02:00' are fine in RFC 3339 but a missing 'T' separator is not.
Related errors
- Invalid duration format: {}
- Invalid number: {}
- Unknown time unit: {}
- No paired devices found. Pair a device first with: sd networ
- Remote device {} is not online
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/834bb3f0c12e1b34.
Report an issue: GitHub.