nautechsystems/nautilus_trader · error · anyhow::Error
AX fills total_count changed during pagination: expected {ex
Error message
AX fills total_count changed during pagination: expected {expected}, was {total_count} What it means
The client pins total_count from the first /fills page and requires every subsequent page in the cursor chain to report the identical value. A changed total_count means the pages no longer form a consistent set (rows were added, removed, or restated mid-traversal), so the traversal aborts. Fills are fetched newest-first, so live executions during pagination are the classic cause.
Source
Thrown at crates/adapters/architect_ax/src/http/client.rs:2262
if let Some(limit) = response.limit {
anyhow::ensure!(
(0..=PAGE_SIZE).contains(&limit),
"AX fills applied limit must be between 0 and {PAGE_SIZE}, was {limit}"
);
anyhow::ensure!(
page_len <= limit as usize,
"AX fills page length {page_len} exceeds applied limit {limit}"
);
}
if let Some(total_count) = response.total_count {
anyhow::ensure!(
total_count >= 0,
"AX fills total_count must be non-negative, was {total_count}"
);
if let Some(expected) = expected_total {
anyhow::ensure!(
total_count == expected,
"AX fills total_count changed during pagination: expected {expected}, was {total_count}"
);
} else {
expected_total = Some(total_count);
}
}
for fill in response.fills {
anyhow::ensure!(
seen_trade_ids.insert(fill.trade_id.clone()),
"AX fills pagination returned duplicate trade ID {}",
fill.trade_id
);
fills.push(fill);
}
if let Some(total_count) = expected_total {View on GitHub (pinned to a4b06ed870)
Solutions
- Retry the full request_fill_reports call — it usually converges once trading pauses
- Anchor the query with an explicit start and end (both within the 7-day AX cap) taken before you begin, and prefer a window that is already historical
- Narrow the time window so the cursor chain is shorter and less exposed to concurrent inserts
- If it reproduces on a static, closed window, capture the raw page sequence with curl and report to AX — the total is being mutated server-side
Example fix
// before — open-ended window, races with live fills
let reports = client.request_fill_reports(account_id, None, None).await?;
// after — fixed historical window + retry
let end = clock.timestamp_ns();
let start = end - 6 * 24 * 60 * 60 * 1_000_000_000;
let reports = retry_on_pagination_error(3, || {
client.request_fill_reports(account_id, Some(start), Some(end))
}).await?; Defensive patterns
Strategy: retry
Try / catch
for attempt in 0..3 {
match client.request_fill_reports(account_id, Some(start), Some(end)).await {
Ok(reports) => return Ok(reports),
Err(e) if e.to_string().contains("total_count changed during pagination") => {
log::warn!("fills total drifted (attempt {}); backing off", attempt + 1);
tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await;
}
Err(e) => return Err(e.into()),
}
}
bail!("fills pagination unstable after retries"); Prevention
- Anchor start/end to fixed timestamps before the call instead of None windows
- Schedule fills reconciliation during quiet trading periods or pause execution during the pull
- Keep windows small (day slices) so traversals finish before totals can drift
When it happens
Trigger: request_fill_reports runs while the account is actively trading: a new fill lands between fetching page N and page N+1 and AX reports an incremented total_count. Also triggered when AX corrects or restates historical rows during the traversal.
Common situations: Running fills reconciliation (e.g. report/generation tasks) concurrently with live strategy execution; two strategy instances pulling fills for the same account; passing end=None so the window extends to call time while fills keep arriving.
Related errors
- AX fills pagination returned duplicate trade ID {}
- AX fills pagination returned more unique rows ({}) than tota
- AX fills total_count must be non-negative, was {total_count}
- AX fills returned an empty next_cursor
- AX fills returned an empty page with a next_cursor
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/ff1b36cf092f1d43.
Report an issue: GitHub.