{"record":{"id":"d4e2f6fe4dcc25b0","repo":"nautechsystems/nautilus_trader","slug":"ax-fills-pagination-repeated-cursor-next-cursor","errorCode":null,"errorMessage":"AX fills pagination repeated cursor {next_cursor:?}","messagePattern":"AX fills pagination repeated cursor (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/architect_ax/src/http/client.rs","lineNumber":2298,"sourceCode":"            if let Some(total_count) = expected_total {\n                anyhow::ensure!(\n                    fills.len() as i64 <= total_count,\n                    \"AX fills pagination returned more unique rows ({}) than total_count {total_count}\",\n                    fills.len()\n                );\n            }\n\n            match response.next_cursor {\n                Some(next_cursor) => {\n                    anyhow::ensure!(\n                        !next_cursor.is_empty(),\n                        \"AX fills returned an empty next_cursor\"\n                    );\n                    anyhow::ensure!(\n                        page_len > 0,\n                        \"AX fills returned an empty page with a next_cursor\"\n                    );\n                    anyhow::ensure!(\n                        seen_cursors.insert(next_cursor.clone()),\n                        \"AX fills pagination repeated cursor {next_cursor:?}\"\n                    );\n                    params.cursor = Some(next_cursor);\n                }\n                None => break,\n            }\n        }\n\n        if let Some(total_count) = expected_total {\n            anyhow::ensure!(\n                fills.len() as i64 == total_count,\n                \"AX fills pagination returned {} unique rows, expected {total_count}\",\n                fills.len()\n            );\n        }\n\n        let ts_init = self.generate_ts_init();","sourceCodeStart":2280,"sourceCodeEnd":2316,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/architect_ax/src/http/client.rs#L2280-L2316","documentation":"Every accepted next_cursor is inserted into a seen_cursors HashSet; a cursor repeating within one traversal means the chain loops, and continuing would fetch the same pages forever. The guard converts that would-be infinite loop into an immediate error with the offending cursor value.","triggerScenarios":"AX echoes the request cursor back when it has nothing new to serve; the cursor generation has a bug and re-issues a token for an already-served page; a page of exactly PAGE_SIZE rows triggers stale cursor regeneration at the boundary.","commonSituations":"Long-running reconciliation traversals that hit server cursor-cache expiry mid-chain; mismatched adapter/server API versions; paginating with parameters the server's cursor implementation does not support (custom sort).","solutions":["Retry the full traversal — transient cursor-cache issues on the server often clear","Capture the full cursor chain with curl and verify no legitimate loop exists in the raw responses","Confirm the adapter version matches the AX API version you connect to (cursor formats change between versions)","Report to AX with the chain if it loops deterministically — this cannot be worked around client-side"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.request_fill_reports(account_id, start, end).await {\n    Ok(reports) => Ok(reports),\n    Err(e) if e.to_string().contains(\"repeated cursor\") => {\n        log::error!(\"AX cursor chain loops on {e}; aborting to avoid infinite pagination\");\n        Err(e) // never retry-loop here — the guard exists to stop a server-side loop\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Treat repeated-cursor errors as a server incident signal, not transient noise — alert ops","Keep adapter and AX API versions in lockstep; cursor formats are version-sensitive","Cap reconciliation frequency so a looping chain cannot hammer the API via scheduled retries"],"tags":["architect-ax","fills","pagination","cursor","infinite-loop"],"backgroundTag":"invalid-pagination-cursor","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}