{"record":{"id":"971c8e017f7a90dc","repo":"nautechsystems/nautilus_trader","slug":"start-must-not-be-later-than-end","errorCode":null,"errorMessage":"start must not be later than end","messagePattern":"start must not be later than end","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/http/data_api.rs","lineNumber":407,"sourceCode":"    #[expect(clippy::too_many_arguments)]\n    pub async fn request_trade_ticks(\n        &self,\n        instrument_id: InstrumentId,\n        condition_id: &str,\n        token_id: &str,\n        price_precision: u8,\n        size_precision: u8,\n        start: Option<UnixNanos>,\n        end: Option<UnixNanos>,\n        limit: Option<u32>,\n    ) -> anyhow::Result<Vec<TradeTick>> {\n        const PAGE_SIZE: u32 = 500;\n        const MAX_OFFSET: u32 = 10_000;\n\n        if let (Some(start), Some(end)) = (start, end)\n            && start > end\n        {\n            anyhow::bail!(\"start must not be later than end\");\n        }\n\n        if limit == Some(0) {\n            anyhow::bail!(\"limit must be greater than zero\");\n        }\n\n        let start_secs = start.map(|value| (value.as_u64() / 1_000_000_000) as i64);\n        let end_secs = end.map(|value| (value.as_u64() / 1_000_000_000) as i64);\n        let protocol = OffsetProtocol::new(\n            \"/trades\",\n            PAGE_SIZE as usize,\n            trade_page_fingerprint,\n            Some((\n                MAX_OFFSET,\n                TradeTickStop::VenueOffsetCeiling(OffsetCeilingSource::Local),\n            )),\n        );\n        let reducer = TradeTickReducer {","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/http/data_api.rs#L389-L425","documentation":"request_trade_ticks validates its time range up front: when both start and end timestamps are provided, start must not exceed end. An inverted range would produce an empty or nonsensical pagination window, so the call is rejected immediately.","triggerScenarios":"Calling request_trade_ticks with a start Unix-ms timestamp strictly greater than the end timestamp (e.g. (Some(start), Some(end)) where start > end).","commonSituations":"Swapped argument order at the call site; computing end from a 'now' variable captured before start in async code; unit mix-ups (seconds vs milliseconds) making start appear later; translating inclusive/exclusive bounds incorrectly across systems.","solutions":["Swap or recompute the arguments so start <= end.","Check timestamp units: the API takes Unix milliseconds (nanoseconds are converted internally); ensure both bounds use the same unit.","When start and end are computed at different times, capture 'now' once and derive both bounds from it.","Guard the call site with an assertion before invoking the API."],"exampleFix":"// before\nlet (start, end) = (end_ts, start_ts); // swapped\napi.request_trade_ticks(Some(cid), Some(start), Some(end), None).await?;\n// after\nassert!(start_ts <= end_ts);\napi.request_trade_ticks(Some(cid), Some(start_ts), Some(end_ts), None).await?;","handlingStrategy":"validation","validationCode":"// Rust: validate the range before calling\nfn valid_range(start: Option<u64>, end: Option<u64>) -> bool {\n    matches!((start, end), (None, _) | (_, None) | (Some(s), Some(e)) if s <= e)\n}\nassert!(valid_range(start_ts, end_ts));","typeGuard":"fn ordered_range(start: u64, end: u64) -> Option<(u64, u64)> {\n    (start <= end).then_some((start, end))\n}","tryCatchPattern":null,"preventionTips":["Compute start and end from a single 'now' timestamp to avoid ordering drift.","Use one consistent unit (Unix milliseconds) for all timestamps.","Add a debug assertion on time ranges at every call site."],"tags":["polymarket","data-api","argument-validation","rust"],"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"}