nautechsystems/nautilus_trader · error

Snapshot interval exceeds u64

Error message

Snapshot interval exceeds u64

What it means

`DataEngine::schedule_book_snapshotter` converts the snapshot interval (NonZeroUsize milliseconds) to u64 and `.expect`s the conversion succeeds, then derives a nanosecond interval. The try_from only fails on platforms where usize is wider than u64 (128-bit usize), which the library treats as an unsupported configuration.

Source

Thrown at crates/data/src/engine/mod.rs:4409

            if let Some(snapshotter) = self.book_snapshotters.remove(&interval_ms) {
                let timer_name = snapshotter.timer_name;
                let mut clock = self.clock.borrow_mut();
                if clock.timer_exists(&timer_name) {
                    clock.cancel_timer(&timer_name);
                }
            }
        }

        BookSnapshotUnsubscribeResult::Removed
    }

    fn schedule_book_snapshotter(
        &mut self,
        interval_ms: NonZeroUsize,
        snapshot_infos: BookSnapshotInfos,
    ) {
        let interval_ms_u64 =
            u64::try_from(interval_ms.get()).expect("Snapshot interval exceeds u64");
        let interval_ns = DurationNanos::from_millis(interval_ms_u64);
        let now_ns = self.clock.borrow().timestamp_ns();
        let start_time_ns = now_ns
            .floor(interval_ns)
            .checked_add(interval_ns)
            .expect("Book snapshot timer start exceeds UnixNanos range");

        let snapshotter = Rc::new(BookSnapshotter::new(
            interval_ms,
            snapshot_infos,
            self.cache.clone(),
        ));
        let timer_name = snapshotter.timer_name;
        let snapshotter_callback = snapshotter.clone();
        let callback_fn: Rc<dyn Fn(TimeEvent)> =
            Rc::new(move |event| snapshotter_callback.snapshot(event));
        let callback = TimeEventCallback::from(callback_fn);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Build for a standard 64-bit target (x86_64/aarch64) where usize == u64 and this cannot fire
  2. If porting to an unusual target, clamp/validate the interval to u64 range before scheduling
  3. This indicates a platform/toolchain problem — verify the Rust target triple used for the build

Example fix

// before
let interval_ms_u64 = u64::try_from(interval_ms.get()).expect("Snapshot interval exceeds u64");
// after (caller-side guard, portable targets)
let ms = interval_ms.get();
assert!(ms <= u64::MAX as usize, "snapshot interval too large");
let interval_ms_u64 = ms as u64;
Defensive patterns

Strategy: validation

Validate before calling

// Rust: bound the interval before scheduling
let ms = interval_ms.get();
assert!(ms <= u64::MAX as usize, "snapshot interval exceeds u64");

Try / catch

let result = std::panic::catch_unwind(|| engine.schedule_book_snapshotter(interval_ms, infos));

Prevention

When it happens

Trigger: Running on a target where `usize` exceeds 64 bits and passing a snapshot interval that doesn't fit in u64; practically unreachable on 64-bit platforms but armed as an invariant guard.

Common situations: Exotic/embedded or non-standard Rust targets with oversized usize; defensive check hit during fuzzing or platform porting work.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/49c98f4de6bec451. Report an issue: GitHub.