nautechsystems/nautilus_trader · error

Either venue_order_id or client_order_id must be provided

Error message

Either venue_order_id or client_order_id must be provided

What it means

get_order_status requires an identifier to look up the order: either a venue_order_id or a client_order_id. When both are None, the client cannot query AX and bails with this error before making a request.

Source

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

    /// - The HTTP request fails.
    #[expect(clippy::too_many_arguments)]
    pub async fn request_order_status(
        &self,
        account_id: AccountId,
        instrument_id: InstrumentId,
        client_order_id: Option<ClientOrderId>,
        venue_order_id: Option<VenueOrderId>,
        order_side: Option<OrderSide>,
        order_type: OrderType,
        time_in_force: TimeInForce,
    ) -> anyhow::Result<OrderStatusReport> {
        let resp = if let Some(ref voi) = venue_order_id {
            self.inner.get_order_status_by_id(voi.as_str()).await
        } else if let Some(ref coid) = client_order_id {
            let cid = client_order_id_to_cid(coid);
            self.inner.get_order_status_by_cid(cid).await
        } else {
            anyhow::bail!("Either venue_order_id or client_order_id must be provided")
        }
        .map_err(|e| anyhow::anyhow!(e))?;

        let detail = resp.status;
        let size_precision = self
            .get_instrument(&detail.symbol)
            .map_or(0, |i| i.size_precision());

        let voi = VenueOrderId::new(&detail.order_id);
        let order_status = detail.state.into();
        let filled = detail.filled_quantity.unwrap_or(0);
        let remaining = detail.remaining_quantity.unwrap_or(0);
        let quantity = Quantity::new((filled + remaining) as f64, size_precision);
        let filled_qty = Quantity::new(filled as f64, size_precision);
        let ts_init = self.generate_ts_init();

        let resolved_coid = client_order_id.or_else(|| detail.clord_id.map(cid_to_client_order_id));

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Provide the client_order_id (the adapter converts it to a cid for AX)
  2. Provide the venue_order_id if you have one from a prior order-status/update event
  3. Ensure at least one of the two Option arguments is Some before calling

Example fix

// before
let status = client.get_order_status(None, None).await?;
// after
let status = client.get_order_status(None, Some(client_order_id)).await?;
Defensive patterns

Strategy: validation

Validate before calling

if venue_order_id.is_none() && client_order_id.is_none() {
    return Err(anyhow::anyhow!("need venue_order_id or client_order_id for order status"));
}

Type guard

fn has_order_id(venue: &Option<VenueOrderId>, client: &Option<ClientOrderId>) -> bool {
    venue.is_some() || client.is_some()
}

Try / catch

match client.get_order_status(venue_order_id, client_order_id).await {
    Err(e) if e.to_string().contains("Either venue_order_id or client_order_id") => {
        anyhow::bail!("caller forgot to attach an order id")
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling the order-status method with neither venue_order_id nor client_order_id supplied — e.g. both Option arguments left as None.

Common situations: Passing unwrapped/order IDs that were never assigned (order rejected before venue order id existed) and also leaving client_order_id None; generic wrapper code forwarding optional IDs without checking at least one exists.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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