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(&params)
                .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.limit

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log the requested vs returned offsets and the raw page to identify the divergence.
  2. Verify the AX pagination contract (offset semantics, clamping) and update the client if needed.
  3. Retry the full pagination from offset 0 to get a consistent snapshot.
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/1d5fd78e119f6c14. Report an issue: GitHub.