nautechsystems/nautilus_trader · error
Timer '{name}' alert time {} was in the past (current time i
Error message
Timer '{name}' alert time {} was in the past (current time is {ts_now}) What it means
set_time_alert_ns validates that a one-shot timer alert time is in the future. When the alert time is already past, the live clock variant rejects the request via anyhow::bail so the caller knows the alert can never fire at the requested instant; the test/backtest clock variant instead silently adjusts the alert to now for immediate firing (per the warn branch). This prevents scheduling an alert that would be missed.
Source
Thrown at crates/common/src/clock.rs:808
name: &str,
mut alert_time_ns: UnixNanos,
allow_past: Option<bool>,
ts_now: UnixNanos,
) -> anyhow::Result<(Ustr, UnixNanos)> {
check_valid_string_utf8(name, stringify!(name))?;
let name = Ustr::from(name);
let allow_past = allow_past.unwrap_or(true);
if alert_time_ns < ts_now {
if allow_past {
log::warn!(
"Timer '{name}' alert time {} was in the past, adjusted to current time for immediate firing",
alert_time_ns.to_rfc3339(),
);
alert_time_ns = ts_now;
} else {
anyhow::bail!(
"Timer '{name}' alert time {} was in the past (current time is {ts_now})",
alert_time_ns.to_rfc3339(),
);
}
}
Ok((name, alert_time_ns))
}
/// Validates and normalizes parameters for an interval timer.
///
/// A missing or zero `start_time_ns` resolves to `ts_now`. `allow_past` defaults to `true`, and
/// `fire_immediately` defaults to `false`. Returns the interned name, normalized start and stop
/// times, and resolved flag values.
///
/// # Errors
///
/// Returns an error if:View on GitHub (pinned to 18893faf8b)
Solutions
- Clamp or recompute the alert time before calling: if alert_time_ns <= clock.timestamp_ns(), either skip or use the current time plus a small delta.
- Pass a time source consistent with the clock: derive alert times from clock.timestamp_ns(), not wall time from another machine.
- Use a TestClock/backtest clock if replaying historical alerts, where past alerts are adjusted rather than rejected.
- Catch the error and log/skip the alert if firing in the past is meaningless for your strategy.
Example fix
// before
clock.set_time_alert_ns("my_alert", stale_alert_time_ns);
// after
let now = clock.timestamp_ns();
let alert_time_ns = if stale_alert_time_ns <= now { now + 1_000_000_000 } else { stale_alert_time_ns };
clock.set_time_alert_ns("my_alert", alert_time_ns); Defensive patterns
Strategy: validation
Validate before calling
fn ensure_future_alert(clock: &dyn Clock, name: &str, alert_time_ns: u64) -> anyhow::Result<u64> {
let now = clock.timestamp_ns();
if alert_time_ns <= now {
anyhow::bail!("alert '{name}' time {alert_time_ns} is in the past (now {now})");
}
Ok(alert_time_ns)
} Try / catch
match clock.set_time_alert_ns(name, alert_time) {
Ok(()) => {},
Err(e) if e.to_string().contains("was in the past") => log::warn!("skipping stale alert: {e}"),
Err(e) => return Err(e),
} Prevention
- Always derive alert times from clock.timestamp_ns(), never external wall clocks
- Validate timestamps are in the future before scheduling
- When replaying saved configs, rebase times onto the current session start
- Know whether your clock variant (live vs test) adjusts or rejects past alerts
When it happens
Trigger: Calling set_time_alert_ns (or its Cython wrapper) on a LiveClock with an alert_time_ns earlier than the current clock timestamp, with the allow-past adjustment disabled.
Common situations: Replaying a stored strategy config whose alert timestamps are stale; system clock skew between machines; computing an alert from an old event timestamp in live trading; DST/manual clock changes pushing 'now' past a precomputed alert time.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Timer '{name}' next event time {} would be in the past (curr
- Timer '{name}' stop time {} is in the past (current time is
- Timer '{name}' stop time {} must be after start time {}
- Event '{}' should have associated handler
- system clock is before UNIX epoch
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d40ceda62d8666d8.
Report an issue: GitHub.