nautechsystems/nautilus_trader · error · anyhow::Error

Either client_order_ids or venue_order_ids must be provided

Error message

Either client_order_ids or venue_order_ids must be provided

What it means

Raised by cancel_orders when neither client_order_ids nor venue_order_ids is provided (both None). BitMEX's cancel endpoint requires order identifiers; there is no 'cancel without ID' mode on this HTTP method. The adapter refuses to build a request that would be invalid.

Source

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

            }
            params.order_id(
                venue_order_ids
                    .iter()
                    .map(|id| id.to_string())
                    .collect::<Vec<_>>(),
            );
        } else if let Some(client_order_ids) = client_order_ids {
            if client_order_ids.is_empty() {
                anyhow::bail!("client_order_ids cannot be empty");
            }
            params.cl_ord_id(
                client_order_ids
                    .iter()
                    .map(|id| id.to_string())
                    .collect::<Vec<_>>(),
            );
        } else {
            anyhow::bail!("Either client_order_ids or venue_order_ids 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 ts_init = self.generate_ts_init();
        let instrument = self.instrument_from_cache(instrument_id.symbol.inner())?;

        let mut reports = Vec::new();

        for order in orders {
            reports.push(parse_order_status_report(
                &order,
                &instrument,
                &self.order_type_cache,
                ts_init,
            )?);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass at least one of client_order_ids or venue_order_ids
  2. Ensure the upstream order object carries a valid client_order_id or venue_order_id before cancelling
  3. Use cancel_all_orders instead if the goal is to clear all orders on a symbol

Example fix

// before
client.cancel_orders(cmd.client_order_ids, cmd.venue_order_ids).await?;
// after
ensure!(cmd.client_order_ids.is_some() || cmd.venue_order_ids.is_some(), "no order ids to cancel");
client.cancel_orders(cmd.client_order_ids, cmd.venue_order_ids).await?;
Defensive patterns

Strategy: validation

Validate before calling

ensure!(client_order_ids.is_some() || venue_order_ids.is_some(), "cancel_orders requires order ids");
client.cancel_orders(client_order_ids, venue_order_ids).await?;

Type guard

fn has_any_id(c: &Option<Vec<ClientOrderId>>, v: &Option<Vec<VenueOrderId>>) -> bool {
    c.as_ref().is_some_and(|x| !x.is_empty()) || v.as_ref().is_some_and(|x| !x.is_empty())
}

Try / catch

match client.cancel_orders(client_order_ids, venue_order_ids).await {
    Ok(reports) => { /* handle */ }
    Err(e) if e.to_string().contains("must be provided") => { /* surface input bug */ }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling cancel_orders(None, None). Happens when caller logic conditionally builds both ID lists and both end up None, or a default-arguments call path omits both.

Common situations: Generic cancel wrappers that forward optional IDs from upstream commands where the order execution engine did not populate either identifier.

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