{"record":{"id":"d8c33fe4f9014cde","repo":"nautechsystems/nautilus_trader","slug":"invalid-time-range-start-start-end-end","errorCode":null,"errorMessage":"Invalid time range: start={start:?} end={end:?}","messagePattern":"Invalid time range: start=(.+?) end=(.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/bitmex/src/http/client.rs","lineNumber":2123,"sourceCode":"\n    /// Request multiple order status reports.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - Credentials are missing.\n    /// - The request fails.\n    /// - The API returns an error.\n    pub async fn request_order_status_reports(\n        &self,\n        instrument_id: Option<InstrumentId>,\n        open_only: bool,\n        start: Option<Timestamp>,\n        end: Option<Timestamp>,\n        limit: Option<u32>,\n    ) -> anyhow::Result<Vec<OrderStatusReport>> {\n        if let (Some(start), Some(end)) = (start, end) {\n            anyhow::ensure!(\n                start < end,\n                \"Invalid time range: start={start:?} end={end:?}\",\n            );\n        }\n\n        let mut params = GetOrderParamsBuilder::default();\n\n        if let Some(instrument_id) = &instrument_id {\n            params.symbol(instrument_id.symbol.as_str());\n        }\n\n        if open_only {\n            params.filter(serde_json::json!({\n                \"open\": true\n            }));\n        }\n\n        if let Some(start) = start {","sourceCodeStart":2105,"sourceCodeEnd":2141,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bitmex/src/http/client.rs#L2105-L2141","documentation":"request_reports (bulk order history query) validates that when both start and end timestamps are provided, start must be strictly before end. anyhow::ensure! raises this error otherwise. It guards against sending BitMEX a reversed or zero-width time range that would return no useful data.","triggerScenarios":"Calling the bulk order report request with start == end (zero-width window), or with start after end — typically from swapping arguments, computing boundaries inclusively/exclusively incorrectly, or a clock-skewed timestamp source producing end in the past.","commonSituations":"Building a daily batch job with inclusive end-of-day timestamps equal to the next job's start; unit/integration tests using identical fixed timestamps for start and end; misconfiguring a reporting window where start/end come from env or config in different orders or timezones.","solutions":["Swap start and end so start < end before calling, or normalize with min/max.","Make the end exclusive and advance it by at least one nanosecond past start for zero-width requests.","Validate the configured reporting window at load time and fail fast with a clear config error.","If only one bound is meaningful, pass None for the other instead of a degenerate pair."],"exampleFix":"// before\nlet (start, end) = (end_ts, start_ts); // accidentally swapped\nclient.request_reports(instrument_id, open_only, Some(start), Some(end), limit).await?;\n// after\nlet (lo, hi) = if start_ts <= end_ts { (start_ts, end_ts) } else { (end_ts, start_ts) };\nclient.request_reports(instrument_id, open_only, Some(lo), Some(hi), limit).await?;","handlingStrategy":"validation","validationCode":"fn valid_range(start: Option<Timestamp>, end: Option<Timestamp>) -> bool {\n    match (start, end) {\n        (Some(s), Some(e)) => s < e,\n        _ => true,\n    }\n}","typeGuard":"fn normalize_range(start: Timestamp, end: Timestamp) -> (Timestamp, Timestamp) {\n    if start <= end { (start, end) } else { (end, start) }\n}","tryCatchPattern":"if !valid_range(start, end) {\n    return Err(anyhow::anyhow!(\"report window: start must be before end\"));\n}\nlet reports = client.request_reports(instrument_id, open_only, start, end, limit).await?;","preventionTips":["Normalize window boundaries with min/max before calling.","Use exclusive end boundaries and ensure end > start by at least one tick.","Validate time-range config values at startup, not per request.","In tests, avoid using identical fixed timestamps for start and end."],"tags":["validation","time-range","arguments","bitmex"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}