nautechsystems/nautilus_trader · error · anyhow::Error
Failed to fetch fills: {e}
Error message
Failed to fetch fills: {e} What it means
This error wraps any failure from `fetch_all_fills` — the paginated Coinbase fill (execution) history endpoint — while building fill reports. It means the HTTP/API call for trade history failed (network, auth, invalid query params, rate limiting). It is thrown because execution reports cannot be generated without the fills list.
Source
Thrown at crates/adapters/coinbase/src/http/client.rs:1265
instrument_id: Option<InstrumentId>,
venue_order_id: Option<VenueOrderId>,
start: Option<Timestamp>,
end: Option<Timestamp>,
limit: Option<u32>,
) -> anyhow::Result<Vec<FillReport>> {
let query = FillListQuery {
product_id: instrument_id.map(|id| id.symbol.as_str().to_string()),
venue_order_id: venue_order_id.map(|id| id.as_str().to_string()),
start,
end,
limit,
};
let fills = self
.inner
.fetch_all_fills(&query)
.await
.map_err(|e| anyhow::anyhow!("Failed to fetch fills: {e}"))?;
let ts_init = self.ts_now();
let mut reports = Vec::with_capacity(fills.len());
for fill in &fills {
let instrument = match self.get_or_fetch_instrument(fill.product_id).await {
Ok(inst) => inst,
Err(e) => {
log::debug!("Skipping fill {}: {e}", fill.trade_id);
continue;
}
};
match parse_fill_report(fill, &instrument, account_id, ts_init) {
Ok(report) => reports.push(report),
Err(e) => log::warn!("Failed to parse fill {}: {e}", fill.trade_id),
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the inner error chain for the root cause (HTTP status, Coinbase message).
- Validate the product_id filter format (BTC-USDT style) and the start/end window.
- Verify API key permissions include fill/trade history access.
- Retry transient errors (timeouts, 5xx, 429) with backoff and resume pagination from the last cursor.
- Narrow the queried time window or paginate in smaller chunks.
Example fix
// before: one-shot deep history pull
let reports = client.request_fill_status_reports(account_id, None, None, None).await?;
// after: chunked windows to avoid rate limits
for (start, end) in chunk_days(requested_start, requested_end, 7) {
let reports = client.request_fill_status_reports(account_id, None, Some(start), Some(end)).await?;
process(reports);
} Defensive patterns
Strategy: retry
Validate before calling
if let (Some(s), Some(e)) = (start, end) {
assert!(e > s, "fill query end must be after start");
} Try / catch
match client.request_fill_status_reports(account_id, instrument_id, start, end).await {
Ok(reports) => reports,
Err(e) if is_retryable(&e) => retry_with_backoff(3, Duration::from_secs(1), || {
client.request_fill_status_reports(account_id, instrument_id, start, end)
}).await?,
Err(e) => { tracing::error!("fetch fills failed: {e}"); return Err(e); }
} Prevention
- Use Coinbase-format product ids for filters.
- Query fills in bounded time windows rather than unbounded history.
- Check key scope for fill history before large backfills.
- Honor rate-limit headers during pagination.
When it happens
Trigger: Calling the fills-report method at client.rs:1265 with a fills query whose paginated `fetch_all_fills` call fails: invalid product_id filter, out-of-range start/end window, 401 auth, 429 rate limit, network interruption mid-pagination.
Common situations: Backfilling execution history for reconciliation with an invalid time window; querying fills with a misformatted product id; credential rotation invalidating keys mid-run; rate limits when paginating deep fill history.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Failed to fetch products: {e}
- Failed to fetch order: {e}
- Failed to fetch CFM balance summary: {e}
- Failed to fetch CFM positions: {e}
- Failed to fetch CFM position '{product_id}': {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fff9e2af82cf9b14.
Report an issue: GitHub.