{"record":{"id":"8a4449e2f8f0eeda","repo":"nautechsystems/nautilus_trader","slug":"failed-to-fetch-lighter-fills","errorCode":null,"errorMessage":"failed to fetch Lighter fills","messagePattern":"failed to fetch Lighter fills","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/execution.rs","lineNumber":5274,"sourceCode":"                trade_type: None,\n                limit: LIGHTER_REST_PAGE_SIZE,\n                aggregate: None,\n            });\n\n            let response = match self.http_client.get_trades(&query).await {\n                Ok(response) => response,\n                Err(e) => {\n                    // `{e:#}` preserves the venue's status/body across the\n                    // outer context wrap; `scrub_auth` redacts any `auth=`\n                    // query value the HTTP layer's error included.\n                    log::warn!(\n                        \"Lighter get_trades failed (market_id={:?}, account_index={}, cursor={:?}): {}\",\n                        query.market_id,\n                        credential.account_index(),\n                        cursor,\n                        scrub_auth(&format!(\"{e:#}\")),\n                    );\n                    return Err(anyhow::Error::new(e).context(\"failed to fetch Lighter fills\"));\n                }\n            };\n\n            for trade in &response.trades {\n                let Some(instrument_id) = self.registry.instrument_id(trade.market_id) else {\n                    anyhow::bail!(\n                        \"no Lighter instrument registered for fill market_index={}\",\n                        trade.market_id,\n                    );\n                };\n                let Some(instrument) = self.core.cache().instrument(&instrument_id).cloned() else {\n                    anyhow::bail!(\"Lighter fill instrument {instrument_id} missing from cache\");\n                };\n\n                match parse_ws_fill_report(\n                    trade,\n                    credential.account_index(),\n                    &instrument,","sourceCodeStart":5256,"sourceCodeEnd":5292,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/execution.rs#L5256-L5292","documentation":"When fetching fills (trade history) from Lighter via get_trades, a failed HTTP/API call is wrapped as 'failed to fetch Lighter fills'. The request parameters (market_id, account_index, cursor) are logged with auth scrubbed before this error is raised, so callers get pagination context plus the underlying cause.","triggerScenarios":"generate_order_status_reports / fill generation path calls the Lighter get_trades endpoint with a market_id/account_index/cursor and the request returns Err — network failure, 4xx/5xx, auth rejection, or rate limit.","commonSituations":"Backfilling fills after a disconnect, paging through fills with a stale or invalid cursor, expired Lighter API credentials, or venue API downtime during report reconciliation.","solutions":["Read the scrubbed inner error ({e:#}) for the HTTP status and Lighter error code.","Reset pagination and re-fetch from the first page if the cursor was stale/invalid.","Refresh or re-verify Lighter API credentials; auth failures surface here.","Retry with backoff on 429/5xx; fills fetch is safe to re-run since it is read-only."],"exampleFix":"// before\nlet trades = http_client.get_trades(query).await?; // Err -> failed to fetch Lighter fills\n// after\nlet trades = backoff(|| http_client.get_trades(reset_cursor_if_stale(query)).await).await?;","handlingStrategy":"retry","validationCode":"// validate cursor and market id before fetching fills\nassert!(query.market_id.is_some() || query.fetch_all);","typeGuard":null,"tryCatchPattern":"match client.generate_order_status_reports(...).await {\n    Err(e) if format!(\"{e:#}\").contains(\"failed to fetch Lighter fills\") => {\n        // reset cursor to None and retry with backoff\n    }\n    r => r?,\n}","preventionTips":["Reset stale cursors to the first page on fetch failure","Refresh Lighter credentials before long reconciliation jobs","Back off on 429/5xx; the fetch is read-only and safe to re-run","Log with auth scrubbing to share errors safely"],"tags":["rust","lighter","fills","http"],"backgroundTag":"api-request-failed","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"}