nautechsystems/nautilus_trader · error

Invalid time range: start={s:?} end={e:?}

Error message

Invalid time range: start={s:?} end={e:?}

What it means

request_trades validates that, when both start and end timestamps are supplied, start is strictly earlier than end. anyhow::ensure! raises this error otherwise. It is a caller-argument precondition, not a network problem.

Source

Thrown at crates/adapters/deribit/src/http/client.rs:1266

        end: Option<Timestamp>,
        limit: Option<u32>,
    ) -> anyhow::Result<Vec<TradeTick>> {
        // Get instrument from cache to determine precisions
        let (price_precision, size_precision) =
            if let Some(instrument) = self.get_instrument(&instrument_id.symbol.inner()) {
                (instrument.price_precision(), instrument.size_precision())
            } else {
                log::warn!("Instrument {instrument_id} not in cache, skipping trades request");
                return Err(InstrumentLookupError::not_found(instrument_id).into());
            };

        // Convert timestamps to milliseconds
        let now = Timestamp::now();
        let end_dt = end.unwrap_or(now);
        let start_dt = start.unwrap_or(end_dt - jiff::SignedDuration::from_hours(1));

        if let (Some(s), Some(e)) = (start, end) {
            anyhow::ensure!(s < e, "Invalid time range: start={s:?} end={e:?}");
        }

        let start_ms = start_dt.as_millisecond();
        let end_ms = end_dt.as_millisecond();
        let ts_init = self.generate_ts_init();
        let mut all_trades = Vec::new();
        let mut paginator = TradePaginator::new(start_ms, end_ms);

        loop {
            let params = GetLastTradesByInstrumentAndTimeParams::new(
                instrument_id.symbol.to_string(),
                paginator.cursor,
                end_ms,
                Some(DERIBIT_HISTORICAL_TRADES_MAX_COUNT),
                Some("asc".to_string()),
            );

            let full_response = self

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Reorder the arguments so start < end.
  2. Default one bound to None and let the client fill it (end defaults to now, start defaults to end - 1 hour).
  3. Add a caller-side check `s < e` before calling request_trades.

Example fix

// before
client.request_trades(bar_type, end, start, None).await?;
// after
assert!(start < end, "start must precede end");
client.request_trades(bar_type, Some(start), Some(end), None).await?;
Defensive patterns

Strategy: validation

Validate before calling

if let (Some(s), Some(e)) = (start, end) {
    assert!(s < e, "request_trades: start must be < end ({s:?} >= {e:?})");
}

Try / catch

let (start, end) = (start.min(end), start.max(end));
let trades = client.request_trades(instrument_id, Some(start), Some(end), None).await?;

Prevention

When it happens

Trigger: Calling request_trades with both start and end provided where start >= end — e.g. swapped arguments, passing the same timestamp for both, or computing end from start incorrectly.

Common situations: Reversed parameter order in a paging loop; using an inclusive 'latest trade time' from a previous request as end while it is already <= the new start; unit confusion producing identical epoch values.

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