{"record":{"id":"6b35cbcb918ce87b","repo":"nautechsystems/nautilus_trader","slug":"cannot-dispatch-request-start-start-ns-was-grea","errorCode":null,"errorMessage":"Cannot dispatch request, start {start_ns} was greater than end {end_ns}","messagePattern":"Cannot dispatch request, start (.+?) was greater than end (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/streaming.rs","lineNumber":232,"sourceCode":"        };\n\n        let now_ns = self.clock.borrow().timestamp_ns();\n        let now_dt = now_ns.to_datetime_utc();\n        let query_past_data = request_params(&req)\n            .and_then(|p| p.get(PARAM_SUBSCRIPTION_NAME))\n            .is_none();\n\n        let (start_dt, end_dt) = bound_request_dates(\n            request_start(&req),\n            request_end(&req),\n            now_dt,\n            query_past_data,\n        );\n        let start_ns = datetime_to_unix_nanos_or_zero(start_dt);\n        let end_ns = datetime_to_unix_nanos_or_zero(end_dt);\n\n        if start_ns > end_ns {\n            anyhow::bail!(\n                \"Cannot dispatch request, start {start_ns} was greater than end {end_ns}\"\n            );\n        }\n\n        let client_id = req.client_id().copied();\n        let venue = req.venue().copied();\n        let used_client_id = self\n            .get_client(client_id.as_ref(), venue.as_ref())\n            .map(|client| client.client_id());\n\n        // Floor the catalog window to the UTC day boundary so the day-start F_SNAPSHOT frame is\n        // selected and read for the snapshot replay; client gaps keep the original window.\n        // The parent request keeps its original start, so the merged response trims back to it.\n        let (catalog_start_dt, catalog_start_ns) = if matches!(req, RequestCommand::BookDeltas(_))\n            && request_params(&req)\n                .and_then(|p| p.get_bool(PARAM_FROM_DAY_START))\n                .unwrap_or(true)\n        {","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/streaming.rs#L214-L250","documentation":"The data engine's dispatch_date_range_request bounds each date-range request into (start_ns, end_ns) unix-nanoseconds and refuses to dispatch when the start is after the end. This guard prevents catalog/client fan-out from iterating an inverted, empty window. It fires after bound_request_dates normalization, so the supplied request dates themselves (possibly clamped) are inverted.","triggerScenarios":"Calling execute_request with a RequestCommand carrying a start datetime strictly later than its end datetime (e.g. start=2024-06-01, end=2024-05-01), such that after bounding against 'now' the start_ns > end_ns.","commonSituations":"Swapping start/end arguments when building a historical data request; passing a start in the future relative to a clamped end; timezone mishandling that shifts one bound across the other; unit mixups (seconds vs ms) that make the start parse far later than the end.","solutions":["Swap or correct the start/end datetimes on the request so start <= end before calling execute_request","Log both datetimes at the call site and verify the normalization (UTC, correct units) applied to them","If the request is intentionally empty/degenerate, skip dispatching rather than sending an inverted range","Validate bounds client-side before issuing any date-range catalog request"],"exampleFix":"// before\nengine.execute_request(cmd_with(start: \"2024-06-01\", end: \"2024-05-01\"))\n// after\nlet (start, end) = (\"2024-05-01\", \"2024-06-01\");\nassert!(start <= end);\nengine.execute_request(cmd_with(start, end));","handlingStrategy":"validation","validationCode":"fn validate_range(start_ns: u64, end_ns: u64) -> Result<(), String> {\n    if start_ns > end_ns { Err(format!(\"start {start_ns} > end {end_ns}\")) } else { Ok(()) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always construct date-range requests with (start, end) in that argument order","Normalize all datetimes to UTC unix nanoseconds before comparing","Unit-test request builders with known inverted-range inputs"],"tags":["rust","data-engine","date-range","validation"],"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"}