nautechsystems/nautilus_trader · warning · anyhow::Error
AX open-orders total_count changed during pagination: expect
Error message
AX open-orders total_count changed during pagination: expected {total_count}, was {} What it means
The Architect AX open-orders paginated fetch tracks the total_count advertised on the first page and asserts every subsequent page reports the same value. If the venue's total changes between page requests, the client aborts rather than return an inconsistent, possibly duplicated or missing, order snapshot. This is an integrity guard for concurrent state churn during offset-based pagination.
Source
Thrown at crates/adapters/architect_ax/src/http/client.rs:2014
anyhow::ensure!(
response.total_count >= 0,
"AX open-orders total_count must be non-negative, was {}",
response.total_count
);
anyhow::ensure!(
response.limit >= 0 && response.limit <= PAGE_SIZE,
"AX open-orders applied limit must be between 0 and {PAGE_SIZE}, was {}",
response.limit
);
anyhow::ensure!(
i64::from(response.offset) == offset,
"AX open-orders response offset mismatch: requested {offset}, was {}",
response.offset
);
let total_count = *expected_total.get_or_insert(response.total_count);
anyhow::ensure!(
response.total_count == total_count,
"AX open-orders total_count changed during pagination: expected {total_count}, was {}",
response.total_count
);
let page_len = i64::try_from(response.orders.len())
.context("AX open-orders page length exceeds i64")?;
anyhow::ensure!(
page_len <= i64::from(response.limit),
"AX open-orders page length {page_len} exceeds applied limit {}",
response.limit
);
let next_offset = offset
.checked_add(page_len)
.context("AX open-orders offset overflow")?;
anyhow::ensure!(
next_offset <= total_count,
"AX open-orders page exceeds total_count: next offset {next_offset}, total {total_count}"View on GitHub (pinned to 18893faf8b)
Solutions
- Retry the full pagination loop from offset 0 to capture a consistent snapshot
- Reduce polling frequency or fetch during quieter periods
- Fetch with a larger page size to complete pagination in fewer round trips and shrink the mutation window
- Check for bots/strategies concurrently mutating orders on the same account
Example fix
// before
let page = client.open_orders_paginated().await?; // fails if book churns mid-page
// after
let page = retry_with_backoff(3, || async {
client.open_orders_paginated().await
}).await?; // restart pagination on consistency failure Defensive patterns
Strategy: retry
Validate before calling
// Ensure snapshot consistency by re-running pagination on failure
async fn fetch_with_retry<F, T>(mut f: F, attempts: u32) -> anyhow::Result<T>
where F: FnMut() -> anyhow::Result<T> {
for _ in 0..attempts {
match f() {
Ok(v) => return Ok(v),
Err(e) if e.to_string().contains("total_count changed") => continue,
Err(e) => return Err(e),
}
}
anyhow::bail("pagination never reached a consistent snapshot")
} Try / catch
match result {
Err(e) if e.to_string().contains("total_count changed during pagination") => restart_pagination(),
Err(e) => return Err(e),
Ok(orders) => use(orders),
} Prevention
- Retry the entire pagination from offset 0 rather than resuming mid-way
- Increase page size so pagination completes in fewer round trips
- Avoid placing/canceling orders from the same account while polling open orders
- Poll during low-activity windows
When it happens
Trigger: The venue order book mutates between page fetches: an order is created, canceled, or filled while the client pages through open orders, so a later page's total_count differs from the first page's.
Common situations: Active trading periods where orders are placed/canceled mid-poll; polling open orders for an account whose automation runs concurrently; slow multi-page fetches over a fast-moving book.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- AX open-orders pagination did not return the advertised numb
- AX open-orders page length {page_len} exceeds applied limit
- AX open-orders page exceeds total_count: next offset {next_o
- AX open-orders returned rows with total_count zero
- AX open-orders returned an empty page before offset {offset}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7d887db78e4be6aa.
Report an issue: GitHub.