nautechsystems/nautilus_trader · error · anyhow::Error

AX fills returned an empty page with a next_cursor

Error message

AX fills returned an empty page with a next_cursor

What it means

The client received a page with zero fills but a non-null next_cursor. A cursor that yields no rows while claiming more results invites an unbounded or degenerate cursor chain, so the guard requires every continuation page to carry at least one row. The normal terminal condition is next_cursor: None.

Source

Thrown at crates/adapters/architect_ax/src/http/client.rs:2294

                );
                fills.push(fill);
            }

            if let Some(total_count) = expected_total {
                anyhow::ensure!(
                    fills.len() as i64 <= total_count,
                    "AX fills pagination returned more unique rows ({}) than total_count {total_count}",
                    fills.len()
                );
            }

            match response.next_cursor {
                Some(next_cursor) => {
                    anyhow::ensure!(
                        !next_cursor.is_empty(),
                        "AX fills returned an empty next_cursor"
                    );
                    anyhow::ensure!(
                        page_len > 0,
                        "AX fills returned an empty page with a next_cursor"
                    );
                    anyhow::ensure!(
                        seen_cursors.insert(next_cursor.clone()),
                        "AX fills pagination repeated cursor {next_cursor:?}"
                    );
                    params.cursor = Some(next_cursor);
                }
                None => break,
            }
        }

        if let Some(total_count) = expected_total {
            anyhow::ensure!(
                fills.len() as i64 == total_count,
                "AX fills pagination returned {} unique rows, expected {total_count}",
                fills.len()

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Validate the window before calling: start < end, both anchored within the 7-day lookback relative to end, and end not in the future beyond server time
  2. Retry once — boundary races are transient
  3. Reproduce with curl using the exact start/end/limit/sort params and inspect whether an empty page really carries a cursor
  4. If deterministic, report to AX: empty pages must not claim continuation

Example fix

// before — inverted window yields empty pages
client.request_fill_reports(account_id, Some(end_ns), Some(start_ns)).await
// after — start strictly before end, within the 7-day cap
client.request_fill_reports(account_id, Some(start_ns), Some(end_ns)).await
Defensive patterns

Strategy: validation

Validate before calling

// Validate the fills window before calling the API
fn fills_window_valid(start: UnixNanos, end: UnixNanos, now: UnixNanos) -> bool {
    start < end && (end.as_i64() - start.as_i64()) <= 7 * 24 * 60 * 60 * 1_000_000_000 && end <= now
}

if !fills_window_valid(start, end, clock.timestamp_ns()) {
    anyhow::bail!("refusing fills query with invalid window {start}..{end}");
}
client.request_fill_reports(account_id, Some(start), Some(end)).await?;

Try / catch

match client.request_fill_reports(account_id, Some(start), Some(end)).await {
    Ok(reports) => Ok(reports),
    Err(e) if e.to_string().contains("empty page with a next_cursor") => {
        log::error!("AX paged an empty result set; check window and retry: {e}");
        tokio::time::sleep(Duration::from_secs(1)).await;
        client.request_fill_reports(account_id, Some(start), Some(end)).await
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: The start/end window matches no fills but the server does not terminate the cursor chain; rows moved out of the window mid-traversal (corrected timestamps) leaving a page empty; server bug at the boundary page of a large result set.

Common situations: Querying an empty time slice (e.g. a quiet day) on an AX version that always emits a cursor; passing start >= end or a window entirely in the future; racing fill corrections during pagination.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/5ae29876b69ac2cc. Report an issue: GitHub.