{"record":{"id":"d40ceda62d8666d8","repo":"nautechsystems/nautilus_trader","slug":"timer-name-alert-time-was-in-the-past-curr","errorCode":null,"errorMessage":"Timer '{name}' alert time {} was in the past (current time is {ts_now})","messagePattern":"Timer '(.+?)' alert time (.+?) was in the past \\(current time is (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/clock.rs","lineNumber":808,"sourceCode":"    name: &str,\n    mut alert_time_ns: UnixNanos,\n    allow_past: Option<bool>,\n    ts_now: UnixNanos,\n) -> anyhow::Result<(Ustr, UnixNanos)> {\n    check_valid_string_utf8(name, stringify!(name))?;\n\n    let name = Ustr::from(name);\n    let allow_past = allow_past.unwrap_or(true);\n\n    if alert_time_ns < ts_now {\n        if allow_past {\n            log::warn!(\n                \"Timer '{name}' alert time {} was in the past, adjusted to current time for immediate firing\",\n                alert_time_ns.to_rfc3339(),\n            );\n            alert_time_ns = ts_now;\n        } else {\n            anyhow::bail!(\n                \"Timer '{name}' alert time {} was in the past (current time is {ts_now})\",\n                alert_time_ns.to_rfc3339(),\n            );\n        }\n    }\n\n    Ok((name, alert_time_ns))\n}\n\n/// Validates and normalizes parameters for an interval timer.\n///\n/// A missing or zero `start_time_ns` resolves to `ts_now`. `allow_past` defaults to `true`, and\n/// `fire_immediately` defaults to `false`. Returns the interned name, normalized start and stop\n/// times, and resolved flag values.\n///\n/// # Errors\n///\n/// Returns an error if:","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/clock.rs#L790-L826","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nclock.set_time_alert_ns(\"my_alert\", stale_alert_time_ns);\n// after\nlet now = clock.timestamp_ns();\nlet alert_time_ns = if stale_alert_time_ns <= now { now + 1_000_000_000 } else { stale_alert_time_ns };\nclock.set_time_alert_ns(\"my_alert\", alert_time_ns);","handlingStrategy":"validation","validationCode":"fn ensure_future_alert(clock: &dyn Clock, name: &str, alert_time_ns: u64) -> anyhow::Result<u64> {\n    let now = clock.timestamp_ns();\n    if alert_time_ns <= now {\n        anyhow::bail!(\"alert '{name}' time {alert_time_ns} is in the past (now {now})\");\n    }\n    Ok(alert_time_ns)\n}","typeGuard":null,"tryCatchPattern":"match clock.set_time_alert_ns(name, alert_time) {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"was in the past\") => log::warn!(\"skipping stale alert: {e}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["timer","clock","validation","time"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}