nautechsystems/nautilus_trader · error · anyhow::Error

Either client_order_id or venue_order_id must be provided

Error message

Either client_order_id or venue_order_id must be provided

What it means

cancel_order requires at least one order identifier. If neither client_order_id nor venue_order_id is supplied, the request cannot address any order on BitMEX, so the method bails before building the cancel request.

Source

Thrown at crates/adapters/bitmex/src/http/client.rs:1812

    /// - Credentials are missing.
    /// - The request fails.
    /// - The order doesn't exist.
    /// - The API returns an error.
    pub async fn cancel_order(
        &self,
        instrument_id: InstrumentId,
        client_order_id: Option<ClientOrderId>,
        venue_order_id: Option<VenueOrderId>,
    ) -> anyhow::Result<OrderStatusReport> {
        let mut params = super::query::DeleteOrderParamsBuilder::default();
        params.text(NAUTILUS_TRADER);

        if let Some(venue_order_id) = venue_order_id {
            params.order_id(vec![venue_order_id.as_str().to_string()]);
        } else if let Some(client_order_id) = client_order_id {
            params.cl_ord_id(vec![client_order_id.as_str().to_string()]);
        } else {
            anyhow::bail!("Either client_order_id or venue_order_id must be provided");
        }

        let params = params.build().map_err(|e| anyhow::anyhow!(e))?;

        let orders: Vec<BitmexOrder> = self.inner.cancel_orders_response(params).await?;
        let order = orders
            .into_iter()
            .next()
            .ok_or_else(|| anyhow::anyhow!("No order returned in cancel response"))?;

        let instrument = self.instrument_from_cache(instrument_id.symbol.inner())?;
        let ts_init = self.generate_ts_init();

        parse_order_status_report(&order, &instrument, &self.order_type_cache, ts_init)
    }

    /// Cancel multiple orders.
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass the client_order_id for the order to cancel
  2. Pass the venue_order_id if the client_order_id is unavailable
  3. Ensure order identifiers are persisted/looked up before issuing the cancel

Example fix

// before
client.cancel_order(instrument_id, None, None).await?;
// after
client.cancel_order(instrument_id, Some(client_order_id), None).await?;
Defensive patterns

Strategy: validation

Validate before calling

if client_order_id.is_none() && venue_order_id.is_none() {
    return Err(anyhow::anyhow!("cancel_order needs client_order_id or venue_order_id"));
}

Try / catch

match client.cancel_order(instrument_id, client_order_id, venue_order_id).await {
    Ok(o) => o,
    Err(e) if e.to_string().contains("must be provided") => {
        log::error!("cancel skipped: no order identifier available");
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling cancel_order with both identifier parameters None (or passing identifiers of an Option type that resolve to None at runtime).

Common situations: Cancel logic branching on order state where neither ID was captured; passing an untracked order that never received a venue_order_id and whose cl_ord_id was not stored.

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/d9a59c09a55efd53. Report an issue: GitHub.