nautechsystems/nautilus_trader · error

{e}

Error message

{e}

What it means

In the own-order book, `filter_orders` validates the accepted-buffer/timestamp pair before filtering level orders; if `validate_accepted_buffer` returns an Err, the error message is re-panicked. This occurs when `accepted_buffer_ns` is provided without `ts_now` (or an inconsistent combination), so the buffer cannot be meaningfully applied.

Source

Thrown at crates/model/src/orderbook/own.rs:609

/// Filters orders by status and accepted timestamp.
///
/// `accepted_buffer_ns` acts as a grace period after `ts_accepted`. Orders whose
/// `ts_accepted` is still zero (e.g. SUBMITTED/PENDING state before an ACCEPTED
/// event) will pass the buffer check once `ts_now` exceeds the buffer, even though
/// they have not been venue-acknowledged yet. Callers that want to hide inflight
/// orders must additionally filter by `OrderStatus` (for example, include only
/// `ACCEPTED` / `PARTIALLY_FILLED`).
///
/// # Panics
///
/// Panics if `accepted_buffer_ns` is positive and `ts_now` is `None`.
fn filter_orders<'a>(
    levels: impl Iterator<Item = &'a OwnBookLevel>,
    status: Option<&AHashSet<OrderStatus>>,
    accepted_buffer_ns: Option<u64>,
    ts_now: Option<u64>,
) -> IndexMap<Decimal, Vec<OwnBookOrder>> {
    validate_accepted_buffer(accepted_buffer_ns, ts_now).unwrap_or_else(|e| panic!("{e}"));
    let accepted_buffer_ns = accepted_buffer_ns.unwrap_or(0);

    levels
        .map(|level| {
            let orders = level
                .orders
                .values()
                .filter(|order| status.is_none_or(|f| f.contains(&order.status)))
                .filter(|order| {
                    ts_now.is_none_or(|ts_now| {
                        order
                            .ts_accepted
                            .checked_add(DurationNanos::new(accepted_buffer_ns))
                            .is_some_and(|eligible_at| eligible_at.as_u64() <= ts_now)
                    })
                })
                .copied()
                .collect::<Vec<OwnBookOrder>>();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Either pass both `accepted_buffer_ns` and `ts_now`, or pass both as None.
  2. If you only have a buffer, capture a current timestamp (e.g. from the book's ts_init or a clock) and pass it as ts_now.
  3. Read `validate_accepted_buffer` to confirm the exact constraint and satisfy it in the caller.
  4. If stale filtering is not needed, drop accepted_buffer_ns entirely.

Example fix

// before
book.bids_as_map(Some(60_000_000_000), None); // panics: buffer without ts_now
// after
book.bids_as_map(Some(60_000_000_000), Some(ts_now_ns));
Defensive patterns

Strategy: validation

Validate before calling

// Before calling bids_as_map/asks_as_map:
assert_eq!(
    accepted_buffer_ns.is_some(),
    ts_now.is_some(),
    "accepted_buffer_ns and ts_now must be supplied together"
);

Prevention

When it happens

Trigger: Calling `bids_as_map`/`asks_as_map` (which call `filter_orders`) passing `accepted_buffer_ns: Some(x)` while `ts_now: None`, or otherwise violating `validate_accepted_buffer`'s requirement that both are supplied together.

Common situations: Custom own-book snapshot code that sets a buffer for stale-order filtering but forgets to pass the current timestamp; refactored code where the ts_now argument was dropped.

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


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