nautechsystems/nautilus_trader · error
Cannot increment time while clock is in realtime mode
Error message
Cannot increment time while clock is in realtime mode
What it means
increment_time advances the TestClock's internal time, which is only meaningful when the clock is static (test/backtest mode). If the clock is in realtime mode, mutating time manually would violate the clock's invariants, so the operation is rejected with this error. The check is intentionally non-atomic: mode switches must be completed before time operations.
Source
Thrown at crates/core/src/time.rs:281
/// Increments the current static-mode time by `delta` and returns the updated value.
///
/// Internally this uses [`AtomicU64::try_update`] with [`Ordering::AcqRel`] to ensure the increment is
/// atomic and visible to readers using `Acquire` loads.
///
/// # Errors
///
/// Returns an error if the increment would overflow `u64::MAX` or if called
/// while the clock is in real-time mode.
///
/// # Thread Safety
///
/// The mode check is not atomic with the subsequent update. If another thread calls
/// `make_realtime()` between the check and update, the invariant can be violated.
/// This is intentional: mode switching is a setup-time operation and should not
/// occur concurrently with time operations. Callers must ensure mode switches are
/// complete before resuming time operations.
pub fn increment_time(&self, delta: DurationNanos) -> anyhow::Result<UnixNanos> {
anyhow::ensure!(
!self.realtime.load(Ordering::SeqCst),
"Cannot increment time while clock is in realtime mode"
);
let previous =
match self
.timestamp_ns
.try_update(Ordering::AcqRel, Ordering::Acquire, |current| {
current.checked_add(delta.as_u64())
}) {
Ok(prev) => prev,
Err(_) => anyhow::bail!("Cannot increment time beyond u64::MAX"),
};
debug_assert!(
!self.realtime.load(Ordering::SeqCst),
"Invariant: clock must remain in static mode across `increment_time`"
);View on GitHub (pinned to 18893faf8b)
Solutions
- Call the clock's make_static/set_static equivalent before increment_time.
- Use a dedicated TestClock instance for time control and never switch it to realtime in the same test.
- Restructure the code so realtime clocks never receive manual time increments.
Example fix
// before clock.set_realtime(); clock.increment_time(delta)?; // errors // after clock.make_static(); clock.increment_time(delta)?;
Defensive patterns
Strategy: type-guard
Validate before calling
// guard before mutating
if clock.is_realtime() { return Err(anyhow::anyhow!("clock is realtime; cannot increment")); } Type guard
fn is_static(clock: &TestClock) -> bool { !clock.realtime.load(Ordering::SeqCst) } // conceptually; use the public accessor Try / catch
clock.make_static();
clock.increment_time(delta)
.context("failed to advance test clock")?; Prevention
- Complete all mode switches before performing time operations on a clock.
- Use a dedicated TestClock per test and never flip it to realtime when testing time-based logic.
- Keep realtime and test clocks as separate instances in shared infrastructure.
When it happens
Trigger: Calling clock.increment_time(delta) after clock.set_realtime(...) / make_realtime() without switching back to static mode. Typical in tests or live-node code that reuses a TestClock instance that was switched to realtime.
Common situations: Unit tests that flip a clock to realtime mid-test then try to fast-forward; backtest engines accidentally running with a realtime-mode clock; shared clock objects whose mode was changed elsewhere.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- DataActor {} must be registered before calling `clock()` - t
- DataActor {} must be registered before calling `clock_ref()`
- Event '{}' should have associated handler
- dYdX WebSocket stream task is already registered
- default client already registered
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/da1ece7acebbd5cc.
Report an issue: GitHub.