nautechsystems/nautilus_trader · error · anyhow::Error

serde_json deserialization error: {e}

Error message

serde_json deserialization error: {e}

What it means

This error is raised when the JSON returned by Coinbase's `get_order` endpoint cannot be deserialized into the adapter's `OrderResponse` struct via `serde_json::from_value`. It means the response payload shape did not match the expected schema — Coinbase may have changed its API response, or an error/empty body reached deserialization. The adapter throws it because it cannot construct an `OrderStatusReport` from an unrecognized payload.

Source

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

                    .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,
        account_id: AccountId,
        instrument_id: Option<InstrumentId>,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the serde error in the message chain to identify which field failed (missing, type mismatch, null).
  2. Upgrade the coinbase adapter / NautilusTrader to a version matching the current Coinbase API schema.
  3. Log the offending JSON on failure and compare against the expected `OrderResponse` schema.
  4. Check whether the venue_order_id points at a deleted/legacy order returning an unusual payload.
  5. If persistent, pin against the Coinbase API version the adapter was built for or file an adapter issue.

Example fix

// before: opaque failure with no payload context
let response: OrderResponse = serde_json::from_value(json).map_err(|e| anyhow::anyhow!(e))?;
// after: capture payload for diagnosis
let response: OrderResponse = serde_json::from_value(json.clone())
    .map_err(|e| anyhow::anyhow!("order deserialization failed: {e}; payload={json}"))?;
Defensive patterns

Strategy: type-guard

Type guard

fn is_valid_order_json(v: &serde_json::Value) -> bool {
    v.get("order")
        .and_then(|o| o.get("product_id"))
        .and_then(|p| p.as_str())
        .is_some()
}

Try / catch

let response: OrderResponse = serde_json::from_value(json.clone()).map_err(|e| {
    tracing::error!("OrderResponse deserialize failed: {e}; payload={json}");
    anyhow::anyhow!(e)
})?;

Prevention

When it happens

Trigger: Calling `request_order_status_report` when Coinbase returns order JSON missing or with differently-typed fields than `OrderResponse` expects (null in a required field, new nested structure after a Coinbase API version bump, or an error body shaped as valid JSON).

Common situations: Coinbase Advanced Trade API schema updates breaking an outdated adapter version; querying an order whose state produces unexpected null fields; error responses that pass the HTTP layer but fail `from_value`.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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