{"record":{"id":"8daf3c9e0ef215f0","repo":"nautechsystems/nautilus_trader","slug":"lighter-fill-reconciliation-exceeded-max-reconcil","errorCode":null,"errorMessage":"Lighter fill reconciliation exceeded {MAX_RECONCILIATION_PAGES} pages","messagePattern":"Lighter fill reconciliation exceeded (.+?) pages","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/execution.rs","lineNumber":5238,"sourceCode":"            }\n            None => None,\n        };\n\n        let auth = build_auth_token_for(credential)\n            .context(\"failed to mint Lighter auth token for fill fetch\")?;\n\n        let ts_init = self.clock.get_time_ns();\n        let mut reports = Vec::new();\n        let mut cursor: Option<String> = None;\n        let mut seen_cursors = AHashSet::new();\n        let mut seen_in_call = AHashSet::new();\n        let mut pages = 0_usize;\n        let mut oldest_served: Option<UnixNanos> = None;\n        let mut covers_window = true;\n\n        loop {\n            pages += 1;\n            anyhow::ensure!(\n                pages <= MAX_RECONCILIATION_PAGES,\n                \"Lighter fill reconciliation exceeded {MAX_RECONCILIATION_PAGES} pages\",\n            );\n            let query = Zeroizing::new(LighterTradesQuery {\n                authorization: None,\n                auth: Some(auth.clone()),\n                market_id,\n                account_index: Some(credential.account_index()),\n                order_index: None,\n                sort_by: LighterTradeSortBy::Timestamp,\n                sort_dir: Some(LighterSortDirection::Desc),\n                cursor: cursor.clone(),\n                // The venue's `from` parameter is not a timestamp lower bound\n                // and can omit the newest trades when given an epoch value.\n                from_timestamp: None,\n                ask_filter: None,\n                role: None,\n                trade_type: None,","sourceCodeStart":5220,"sourceCodeEnd":5256,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/execution.rs#L5220-L5256","documentation":"Fill reconciliation pages through Lighter trade history with cursors. To prevent infinite pagination (e.g. a cursor loop or a live stream that never reaches the start boundary), the loop is capped at MAX_RECONCILIATION_PAGES pages; exceeding the cap aborts with this error instead of looping forever.","triggerScenarios":"Reconciling a fill window so large it needs more than MAX_RECONCILIATION_PAGES pages of Lighter trades, or the exchange returning cursors that never converge to the requested start timestamp.","commonSituations":"First reconciliation after long downtime with a wide lookback window; very high trade frequency accounts; exchange-side cursor anomalies during API incidents.","solutions":["Narrow the reconciliation time window (start ts) so fills fit within the page cap.","Re-run reconciliation periodically so each run has fewer pages to cover.","Check Lighter API health; a repeating/never-terminating cursor may indicate an exchange-side issue.","If legitimately needed, raise MAX_RECONCILIATION_PAGES in the adapter source and rebuild."],"exampleFix":"// before\nlet query = LighterTradesQuery { /* start far back */ .. };\n// after\nlet query = LighterTradesQuery {\n    // narrow window so pagination stays within MAX_RECONCILIATION_PAGES\n    start_timestamp: Some(now_ms - MAX_WINDOW_MS),\n    ..\n};","handlingStrategy":"validation","validationCode":"let window = now - start;\nif window > MAX_RECON_WINDOW { return Err(anyhow!(\"window too large for one reconciliation pass\")); }","typeGuard":null,"tryCatchPattern":"match res {\n    Err(e) if e.to_string().contains(\"exceeded\") && e.to_string().contains(\"pages\") => split_window_and_reconcile_in_chunks(),\n    other => other,\n}","preventionTips":["Reconcile frequently so each pass paginates few pages","Keep reconciliation time windows within tested bounds","Track reconciliation lag metrics and alert before hitting the cap"],"tags":["pagination","reconciliation","lighter","fills"],"backgroundTag":"pagination-limit-exceeded","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"}