spacedriveapp/spacedrive · error · anyhow::Error

Unknown time unit: {}

Error message

Unknown time unit: {}

What it means

Thrown by parse_duration() when the unit token (lowercased) does not match any arm of its match statement. Supported units are second(s)/sec/s, minute(s)/min/m, hour(s)/h, day(s)/d, and week(s)/w. Notably there is no month or year arm, and multi-word or plural-creative forms like 'fortnights' fail too.

Source

Thrown at apps/cli/src/domains/sync/mod.rs:170

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,
		"day" | "days" | "d" => value * 86400,
		"week" | "weeks" | "w" => value * 604800,
		_ => return Err(anyhow::anyhow!("Unknown time unit: {}", unit)),
	};

	Ok(chrono::Duration::seconds(seconds))
}

fn display_metrics(
	snapshot: &sd_core::service::sync::metrics::snapshot::SyncMetricsSnapshot,
	args: &SyncMetricsArgs,
) {
	// Status header box
	let status_icon = match snapshot.state.current_state {
		DeviceSyncState::Ready => "●".green(),
		DeviceSyncState::Backfilling { .. } => "◐".yellow(),
		DeviceSyncState::CatchingUp { .. } => "◔".yellow(),
		DeviceSyncState::Uninitialized => "○".dark_grey(),
		DeviceSyncState::Paused => "◦".dark_grey(),
	};

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Convert unsupported units to supported ones: '1 month ago' -> '30 days ago', '1 year ago' -> '52 weeks ago'
  2. Use the exact accepted abbreviations: s, m, h, d, w (or full words: seconds, minutes, hours, days, weeks)
  3. Use one value-unit pair only; sum multiple durations into a single unit first

Example fix

// accepted units: second|seconds|sec|s, minute|minutes|min|m,
//                 hour|hours|h, day|days|d, week|weeks|w
// before (fails): sd sync metrics --since '1 month ago'
// after:           sd sync metrics --since '30 days ago'
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_UNITS: &[&str] = &[
    "second", "seconds", "sec", "s",
    "minute", "minutes", "min", "m",
    "hour", "hours", "h",
    "day", "days", "d",
    "week", "weeks", "w",
];

let unit = duration_str.split_whitespace().nth(1).unwrap_or("").to_lowercase();
if !SUPPORTED_UNITS.contains(&unit.as_str()) {
    eprintln!("Unit '{}' not supported. Use one of: {} (no months/years)", unit, SUPPORTED_UNITS.join(", "));
    return Ok(());
}

Type guard

fn is_supported_unit(u: &str) -> bool {
    matches!(
        u.to_lowercase().as_str(),
        "second" | "seconds" | "sec" | "s"
            | "minute" | "minutes" | "min" | "m"
            | "hour" | "hours" | "h"
            | "day" | "days" | "d"
            | "week" | "weeks" | "w"
    )
}

Prevention

When it happens

Trigger: --since '1 month ago', '--since "2 years ago"', '--since "90 secs" (note: secs is NOT in the list - only second/seconds/sec/s), '--since "3 hrs ago"' (hrs unsupported; use h/hours).

Common situations: Assuming month/year granularity exists; abbreviations that differ from the accepted set ('secs', 'hrs', 'mins' - only 'min' and 'm' are listed for minutes); composing durations like '1 day 6 hours'.

Related errors


AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16). Data as JSON: /api/errors/eede44cf4c0f9d1c. Report an issue: GitHub.