{"record":{"id":"d85d43d394eedec4","repo":"nautechsystems/nautilus_trader","slug":"binance-futures-fill-report-range-is-incomplete-s","errorCode":null,"errorMessage":"Binance Futures fill report range is incomplete: start {start} precedes complete-history boundary {complete_start}","messagePattern":"Binance Futures fill report range is incomplete: start (.+?) precedes complete-history boundary (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/futures/execution.rs","lineNumber":2467,"sourceCode":"\n        let symbol = format_binance_symbol(&instrument_id);\n        let mut trades = Vec::new();\n        let mut seen_trade_ids = AHashSet::new();\n        let requested_end_time = cmd\n            .end\n            .map(|end| end.as_i64() / NANOSECONDS_IN_MILLISECOND as i64);\n\n        if let Some(start) = cmd.start {\n            let query_start_time = start.as_i64() / NANOSECONDS_IN_MILLISECOND as i64;\n            let query_end_time = requested_end_time.unwrap_or_else(|| {\n                self.clock.get_time_ns().as_i64() / NANOSECONDS_IN_MILLISECOND as i64\n            });\n            anyhow::ensure!(\n                query_start_time <= query_end_time,\n                \"fill report start time must not exceed end time\"\n            );\n            let complete_start = user_trades_complete_start(cmd.ts_init, self.clock.get_time_ns());\n            anyhow::ensure!(\n                start >= complete_start,\n                \"Binance Futures fill report range is incomplete: start {start} precedes complete-history boundary {complete_start}\"\n            );\n            let mut window_start = query_start_time;\n\n            loop {\n                let window_end = window_start\n                    .saturating_add(USER_TRADES_MAX_INTERVAL_MS)\n                    .min(query_end_time);\n                let mut from_id = None;\n\n                loop {\n                    let mut builder = BinanceUserTradesParamsBuilder::default();\n                    builder.symbol(symbol.clone());\n                    builder.limit(USER_TRADES_PAGE_LIMIT);\n\n                    if let Some(cursor) = from_id {\n                        builder.from_id(cursor);","sourceCodeStart":2449,"sourceCodeEnd":2485,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/futures/execution.rs#L2449-L2485","documentation":"Raised in generate_fill_reports when the requested start time precedes the 'complete-history boundary' (complete_start) computed by user_trades_complete_start from cmd.ts_init and the current clock. Binance userTrades lookups older than the retained complete-history window would silently return partial data, so the client refuses incomplete ranges instead of producing misleading fill reports.","triggerScenarios":"Requesting fill reports (via generate_mass_status) with a start timestamp earlier than the boundary the adapter derives for guaranteed-complete Binance user trade history — e.g. querying fills from before the account/data window the adapter can fully reconstruct.","commonSituations":"Backfilling very old fills for mass status, reconciling after long downtime where the requested window extends beyond complete history, or reusing a stale ts_init so the computed boundary is much later than expected.","solutions":["Move cmd.start forward to at least the complete-history boundary reported in the error message (complete_start).","Fetch older fills directly from Binance (account export/older endpoints) instead of via this incomplete-range query.","Check that cmd.ts_init is current; a stale ts_init inflates the boundary artificially.","If you need the older data anyway, accept partial results by adjusting the adapter boundaries — only with full awareness of the correctness tradeoff."],"exampleFix":"// before\nlet cmd = GenerateFillReports::new(None, old_start_ns, None); // old_start_ns < complete_start\n\n// after\nlet complete_start = user_trades_complete_start(cmd_ts_init, clock.get_time_ns());\nlet start_ns = std::cmp::max(old_start_ns, complete_start);\nlet cmd = GenerateFillReports::new(None, start_ns, None);","handlingStrategy":"validation","validationCode":"let complete_start = user_trades_complete_start(cmd_ts_init, clock.get_time_ns());\nif start < complete_start {\n    return Err(format!(\"clamp start to {complete_start} for complete history\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp requested start times to the complete-history boundary","Use exchange exports for history older than the boundary","Keep cmd.ts_init current so the boundary is not inflated"],"tags":["binance","fill-reports","history-boundary","data-completeness"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}