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 = selfView on GitHub (pinned to 18893faf8b)
Solutions
- Reorder the arguments so start < end.
- Default one bound to None and let the client fill it (end defaults to now, start defaults to end - 1 hour).
- 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
- Always construct the window as (t - lookback, t) so ordering is implicit
- Never pass both bounds from independent sources without checking s < e
- Let the client default unbounded sides instead of computing them manually
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
- Binance Futures fill report end time requires start time for
- Invalid time range: start={start:?} end={end:?}
- invalid depth {depth}; supported depths: {DERIBIT_BOOK_VALID
- {reason}
- Deribit does not support resolution '{resolution}'. Supporte
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6bb6107bdf84908d.
Report an issue: GitHub.