nautechsystems/nautilus_trader · error · anyhow::Error
AX open-orders response offset mismatch: requested {offset},
Error message
AX open-orders response offset mismatch: requested {offset}, was {} What it means
A defensive consistency check during open-orders pagination: the offset echoed by AX in the response must equal the offset the client requested. anyhow::ensure! aborts the loop on mismatch, because continuing would skip or duplicate orders. This catches venue-side pagination misbehavior or schema drift.
Source
Thrown at crates/adapters/architect_ax/src/http/client.rs:2007
sort_ts: Some("desc".to_string()),
};
let response = self
.inner
.get_open_orders_page(¶ms)
.await
.map_err(|e| anyhow::anyhow!(e))?;
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.limitView on GitHub (pinned to 18893faf8b)
Solutions
- Log the requested vs returned offsets and the raw page to identify the divergence.
- Verify the AX pagination contract (offset semantics, clamping) and update the client if needed.
- Retry the full pagination from offset 0 to get a consistent snapshot.
- Pin/align the adapter with the currently supported AX API version.
Defensive patterns
Strategy: try-catch
Validate before calling
// verify offset echo before consuming the page
if response.offset != requested_offset {
return Err(anyhow!("AX offset mismatch: requested {requested_offset}, got {}", response.offset));
} Try / catch
match client.request_open_orders_paged().await {
Ok(orders) => orders,
Err(e) if e.to_string().contains("offset mismatch") => {
tracing::warn!("AX pagination desync, restarting from offset 0: {e:#}");
restart_pagination_from_zero().await
}
Err(e) => return Err(e),
}; Prevention
- Restart pagination from offset 0 on any mismatch to get a consistent snapshot.
- Keep the adapter aligned with the AX API's documented offset semantics.
- Log requested vs returned offsets for venue bug reports.
- Avoid mutating order state concurrently with full open-orders pagination where possible.
When it happens
Trigger: Calling the paginated open-orders fetch when a returned page's offset differs from the requested offset — e.g. the venue clamped or reset the offset, or the response struct deserialized a different field into offset after an API change.
Common situations: AX paginating inconsistently under load; AX API version change to pagination semantics; stale client against an updated API; responses passing through a rewriting proxy.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- AX open-orders total_count must be non-negative, was {}
- AX open-orders applied limit must be between 0 and {PAGE_SIZ
- Binance user-trades pagination made no progress
- Execution payload storage is marked ready without its write
- height must be positive, was {self.height}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1d5fd78e119f6c14.
Report an issue: GitHub.