sharkdp/fd · error · anyhow::Error

'{}' is not a valid date or duration. See 'fd --help'.

Error message

'{}' is not a valid date or duration. See 'fd --help'.

What it means

Thrown by extract_time_constraints in src/main.rs:502 when TimeFilter::after(opts.changed_within) returns None. TimeFilter::from_str tries, in order: a jiff Span (duration like '1d2h'), a Timestamp, a civil DateTime, and an '@<unix-secs>' epoch form; if none parse, the --changed-within value is invalid.

Source

Thrown at src/main.rs:502

            return Err(anyhow!(
                "'fd --list-details' is not supported on Windows unless GNU 'ls' is installed."
            ));
        }
    } else {
        return Err(anyhow!(
            "'fd --list-details' is not supported on this platform."
        ));
    };
    Ok(cmd)
}

fn extract_time_constraints(opts: &Opts) -> Result<Vec<TimeFilter>> {
    let mut time_constraints: Vec<TimeFilter> = Vec::new();
    if let Some(ref t) = opts.changed_within {
        if let Some(f) = TimeFilter::after(t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }
    if let Some(ref t) = opts.changed_before {
        if let Some(f) = TimeFilter::before(t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }
    Ok(time_constraints)
}

View on GitHub (pinned to 41532d114e)

Solutions

  1. Use a jiff duration: 'fd --changed-within 1d' or 'fd --changed-within 2h30m'.
  2. Use a date/datetime: 'fd --changed-within 2024-01-01' or 'fd --changed-within "2024-01-01T12:00:00"'.
  3. Use an epoch: 'fd --changed-within @1700000000'. Consult 'fd --help' for accepted formats.

Example fix

// before
fd --changed-within 5

// after
fd --changed-within 5d
Defensive patterns

Strategy: validation

Validate before calling

# accept a jiff duration (e.g. 1d2h), a date, or @<epoch>
if ! printf '%s' "$CW" | grep -Eq '^@?[0-9]+[dhms]?[0-9]*[a-z]*$|^[0-9]{4}-[0-9]{2}-[0-9]{2}'; then
  echo "invalid --changed-within: $CW" >&2; exit 1
fi
fd --changed-within "$CW"

Type guard

fn parses_as_jiff_time(s: &str) -> bool {
    use jiff::{Span, Timestamp, civil::DateTime};
    s.parse::<Span>().is_ok()
        || s.parse::<Timestamp>().is_ok()
        || s.parse::<DateTime>().is_ok()
        || s.strip_prefix('@').map_or(false, |n| n.parse::<u64>().is_ok())
}

Prevention

When it happens

Trigger: Passing 'fd --changed-within foo', 'fd --changed-within 5' (bare number, no unit — jiff Span requires units), or a date string jiff cannot parse.

Common situations: Assuming a bare integer means days; locale-specific date formats jiff rejects; copy-pasting ISO strings with stray whitespace.

Related errors


AI-assisted analysis of sharkdp/fd@41532d114e (2026-08-06). Data as JSON: /data/errors/bb539ede51511de2.json. Report an issue: GitHub.