nautechsystems/nautilus_trader · error · anyhow::Error

Failed to fetch order: {e}

Error message

Failed to fetch order: {e}

What it means

This error wraps any failure from the Coinbase Advanced Trade HTTP `get_order` call made while building an `OrderStatusReport` in `request_order_status_report`. It means the adapter could not retrieve the order from the exchange — the underlying anyhow error (network failure, HTTP error status, auth problem, or API error payload) is formatted into the message. It is thrown because order status reconciliation cannot proceed without the raw order JSON.

Source

Thrown at crates/adapters/coinbase/src/http/client.rs:1175

                    .map_err(|e| anyhow::anyhow!("Failed to fetch orders: {e}"))?;
                let order = orders
                    .into_iter()
                    .next()
                    .ok_or_else(|| anyhow::anyhow!("No order found for client_order_id={cid}"))?;
                let instrument = self.get_or_fetch_instrument(order.product_id).await?;
                let ts_init = self.ts_now();
                return parse_order_status_report(&order, &instrument, account_id, ts_init);
            }
            (None, None) => {
                anyhow::bail!("Either client_order_id or venue_order_id is required")
            }
        };

        let json = self
            .inner
            .get_order(venue_order_id.as_str())
            .await
            .map_err(|e| anyhow::anyhow!("Failed to fetch order: {e}"))?;
        let response: OrderResponse =
            serde_json::from_value(json).map_err(|e| anyhow::anyhow!(e))?;
        let instrument = self
            .get_or_fetch_instrument(response.order.product_id)
            .await?;
        let ts_init = self.ts_now();
        parse_order_status_report(&response.order, &instrument, account_id, ts_init)
    }

    /// Requests order status reports, optionally filtered by instrument, open
    /// status, and time window.
    ///
    /// # Errors
    ///
    /// Returns an error when the HTTP request fails or when any response cannot
    /// be deserialized.
    pub async fn request_order_status_reports(
        &self,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the inner error in the message for the root cause (HTTP status, auth, timeout).
  2. Verify COINBASE API key/secret/passphrase are valid and have the right scope for Advanced Trade.
  3. Confirm the venue_order_id actually exists on the connected Coinbase account and environment (prod vs sandbox).
  4. Retry on transient errors (5xx/timeout/429) with backoff before failing reconciliation.
  5. If only a client_order_id is known, call with client_order_id so the batched list endpoint is used instead.

Example fix

// before: reconciliation fails hard on transient get_order errors
let report = client.request_order_status_report(account_id, None, Some(venue_order_id)).await?;
// after: retry transient failures
let report = match client.request_order_status_report(account_id, None, Some(venue_order_id)).await {
    Ok(r) => r,
    Err(e) if is_transient(&e) => {
        tokio::time::sleep(Duration::from_millis(500)).await;
        client.request_order_status_report(account_id, None, Some(venue_order_id)).await?
    }
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: retry

Validate before calling

if venue_order_id.is_none() && client_order_id.is_none() {
    anyhow::bail!("Either client_order_id or venue_order_id is required");
}
// only query venue_order_ids previously issued by this adapter

Try / catch

match client.request_order_status_report(account_id, None, Some(vid)).await {
    Ok(report) => report,
    Err(e) if is_retryable(&e) => retry_with_backoff(3, Duration::from_millis(500), || {
        client.request_order_status_report(account_id, None, Some(vid))
    }).await?,
    Err(e) => { tracing::error!("order fetch failed: {e}"); return Err(e); }
}

Prevention

When it happens

Trigger: Calling `request_order_status_report` (e.g. via `resolve_order_context` during reconciliation) with a `venue_order_id` whose `get_order` HTTP request fails: network drop, 401/403 auth, 404 unknown order id, 429 rate limit, or any non-success Coinbase response.

Common situations: Reconciliation at startup against a stale/foreign venue_order_id; expired or misconfigured Coinbase API keys; sandbox vs production endpoint mismatch; transient network outage or hitting Coinbase rate limits during mass reconciliation.

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


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