{"record":{"id":"df9c5ab58ce2d00e","repo":"nautechsystems/nautilus_trader","slug":"lighter-fill-reconciliation-repeated-cursor-next","errorCode":null,"errorMessage":"Lighter fill reconciliation repeated cursor `{next}`","messagePattern":"Lighter fill reconciliation repeated cursor `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/execution.rs","lineNumber":5344,"sourceCode":"                .filter_map(|trade| u64::try_from(trade.timestamp).ok())\n                .map(|timestamp_ms| UnixNanos::from(timestamp_ms.saturating_mul(1_000_000)))\n                .min();\n\n            if let Some(page_oldest) = page_oldest {\n                oldest_served = Some(oldest_served.map_or(page_oldest, |ts| ts.min(page_oldest)));\n            }\n\n            let reached_start_boundary = cmd\n                .start\n                .is_some_and(|start| page_oldest.is_some_and(|oldest| oldest < start));\n\n            if reached_start_boundary {\n                break;\n            }\n\n            match response.next_cursor {\n                Some(next) if !next.is_empty() => {\n                    anyhow::ensure!(\n                        seen_cursors.insert(next.clone()),\n                        \"Lighter fill reconciliation repeated cursor `{next}`\",\n                    );\n                    cursor = Some(next);\n                }\n                _ => {\n                    // The venue retains a bounded number of recent trades per account,\n                    // so an exhausted cursor ends the retained history rather than the\n                    // account's. Only a trade older than `start` proves the requested\n                    // window was served in full; an account-wide sweep that served\n                    // nothing has no history to retain.\n                    if let (Some(start), Some(oldest)) = (cmd.start, oldest_served) {\n                        covers_window = false;\n\n                        log::warn!(\n                            \"Lighter fill reports do not cover {} to {}: trade pagination exhausted before the requested start; the venue `export` endpoint serves full history\",\n                            unix_nanos_to_iso8601(start),\n                            unix_nanos_to_iso8601(oldest),","sourceCodeStart":5326,"sourceCodeEnd":5362,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/execution.rs#L5326-L5362","documentation":"During paginated fill reconciliation, each returned next_cursor is inserted into a `seen_cursors` set. If the exchange returns a cursor that was already served, pagination would loop forever, so the adapter fails fast with this error. It detects a server-side cursor cycle.","triggerScenarios":"Lighter trades endpoint returning a repeated next_cursor during paginated fill reconciliation — typically an exchange-side anomaly or API bug, not a client config problem.","commonSituations":"Lighter API incidents where cursor pagination degenerates into a cycle; transient backend issues during heavy load.","solutions":["Retry the reconciliation after a short delay; cursor cycles are usually transient.","Check Lighter status/announcements for known API pagination issues.","Narrow the reconciliation window to reduce reliance on deep pagination.","If persistent, capture the repeated cursor value and report it to Lighter support."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match res {\n    Err(e) if e.to_string().contains(\"repeated cursor\") => {\n        tokio::time::sleep(BACKOFF).await;\n        retry_reconciliation();\n    }\n    other => other,\n}","preventionTips":["Treat repeated-cursor aborts as transient and retry with backoff","Monitor Lighter API status for pagination incidents","Alert on repeated occurrences — persistent cycles need exchange support"],"tags":["pagination","cursor-loop","lighter","fills"],"backgroundTag":"pagination-cursor-loop","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"}