nautechsystems/nautilus_trader · error

seconds timestamp should fit i64

Error message

seconds timestamp should fit i64

What it means

This panic comes from `i64::try_from(epoch_second).expect(...)` inside `write_fixed_prefix` in crates/common/src/generators/order_list_id.rs. The function builds a date-time prefix for generated OrderListId values from a Unix epoch seconds value, and jiff's `Timestamp::from_second` requires an i64. The generator treats an epoch_second that cannot fit in an i64 (or is otherwise unrepresentable) as a hard invariant violation and panics immediately.

Source

Thrown at crates/common/src/generators/order_list_id.rs:146

        self.epoch_second = epoch_second;
    }
}

#[inline]
fn fixed_prefix_capacity(trader_tag: &str, strategy_tag: &str) -> usize {
    "OL-".len()
        + DATETIME_TAG_LEN
        + "-".len()
        + trader_tag.len()
        + "-".len()
        + strategy_tag.len()
        + "-".len()
}

fn write_fixed_prefix(buf: &mut String, trader_tag: &str, strategy_tag: &str, epoch_second: u64) {
    let now_utc = Offset::UTC.to_datetime(
        Timestamp::from_second(
            i64::try_from(epoch_second).expect("seconds timestamp should fit i64"),
        )
        .expect("seconds timestamp should be within valid range"),
    );

    buf.clear();

    write!(
        buf,
        "OL-{:04}{:02}{:02}-{:02}{:02}{:02}-{trader_tag}-{strategy_tag}-",
        now_utc.year(),
        now_utc.month(),
        now_utc.day(),
        now_utc.hour(),
        now_utc.minute(),
        now_utc.second(),
    )
    .expect("writing to String should not fail");
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the clock/timestamp source feeding epoch_second; use the real current time (e.g. `Timestamp::now().as_unix_seconds()` style) instead of a raw counter
  2. Clamp or validate the u64 before calling: if `epoch_second > i64::MAX as u64`, reject or saturate it upstream
  3. If this fires in tests, fix the test fixture to use a realistic epoch value instead of u64::MAX

Example fix

// before
let epoch = u64::MAX; // overflow value from fixture
let _ = generator.refresh_fixed_prefix(epoch);
// after
let epoch = u64::try_from(std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs()).unwrap();
assert!(epoch <= i64::MAX as u64);
let _ = generator.refresh_fixed_prefix(epoch);
Defensive patterns

Strategy: validation

Validate before calling

fn valid_epoch_seconds(secs: u64) -> bool { secs <= i64::MAX as u64 }

Prevention

When it happens

Trigger: Calling `refresh_fixed_prefix` (directly or via OrderListIdGenerator refresh logic) with an `epoch_second: u64` value greater than i64::MAX (9,223,372,036,854,775,807). Only values above ~292 billion years from the epoch trigger this; a normal wall-clock value can never.

Common situations: Practically unreachable in production; seen when tests or fuzzing pass synthetic u64::MAX / huge mock clock values into the generator, or when an uninitialized/overflowing clock counter is fed in as epoch seconds.

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/ea41a3fc671d1486. Report an issue: GitHub.