{"record":{"id":"390e82b1e629fd6c","repo":"nautechsystems/nautilus_trader","slug":"lighter-inactive-order-lookup-repeated-cursor-ne","errorCode":null,"errorMessage":"Lighter inactive-order lookup repeated cursor `{next}`","messagePattern":"Lighter inactive-order lookup repeated cursor `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/websocket/dispatch.rs","lineNumber":1933,"sourceCode":"            ask_filter: None,\n            between_timestamps: None,\n            cursor: cursor.clone(),\n            limit: LIGHTER_REST_PAGE_SIZE,\n        });\n        let inactive = http_client\n            .get_account_inactive_orders(&query)\n            .await\n            .context(\"failed to fetch Lighter inactive orders\")?;\n\n        for order in &inactive.orders {\n            if matches_order(order) {\n                return finalize(order).map(Some);\n            }\n        }\n\n        match inactive.next_cursor {\n            Some(next) if !next.is_empty() => {\n                anyhow::ensure!(\n                    seen_cursors.insert(next.clone()),\n                    \"Lighter inactive-order lookup repeated cursor `{next}`\",\n                );\n                cursor = Some(next);\n            }\n            _ => break,\n        }\n    }\n\n    Ok(None)\n}\n\nfn order_matches_lookup(\n    order_index: i64,\n    client_order_index: i64,\n    target_venue_index: Option<i64>,\n    target_client_index: Option<i64>,\n) -> bool {","sourceCodeStart":1915,"sourceCodeEnd":1951,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/websocket/dispatch.rs#L1915-L1951","documentation":"While paginating the inactive-orders endpoint, the adapter tracks seen cursors; if the venue returns a cursor it already followed, pagination would loop forever, so it fails fast. This detects a broken or non-advancing cursor from the API.","triggerScenarios":"The inactive-orders response repeats a non-empty next_cursor that was already visited — venue API bug, proxy/response caching replaying the same page, or desynced pagination state.","commonSituations":"Caching proxies or rate-limited responses serving stale pages; venue-side pagination bugs during API upgrades; retry layers returning cached responses.","solutions":["Disable or bypass response caching (ensure no-cache headers) between the adapter and Lighter's API.","Retry the lookup later; if reproducible, report the cursor-loop to Lighter support with the cursor value.","Locate the order via direct REST query by order_index instead of cursor pagination."],"exampleFix":"// before: trusting venue cursors blindly\ncursor = Some(next);\n// after: keep the guard, but detect looping and surface the cursor\nanyhow::ensure!(seen_cursors.insert(next.clone()), \"repeated cursor `{next}` — venue pagination not advancing\");","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match lookup { Err(e) if e.to_string().contains(\"repeated cursor\") => { tokio::time::sleep(delay).await; retry_lookup(); }, r => r? }","preventionTips":["Bypass HTTP caches between adapter and venue API","Retry with backoff on cursor loops","Fall back to a direct REST query by order_index"],"tags":["rest","pagination","api-bug"],"backgroundTag":"request-timeout","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"}