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
- Pass the client_order_id for the order to cancel
- Pass the venue_order_id if the client_order_id is unavailable
- 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
- Persist client_order_id for every submitted order
- Only issue cancels for tracked orders
- Prefer client_order_id (clOrdID) since it is known before venue acknowledgment
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
- Either client_order_ids or venue_order_ids must be provided
- Either venue_order_id or client_order_id must be provided
- All {} requests failed: {errors:?}
- `peg_offset_value` requires `peg_price_type`
- Pegged orders only supported for LIMIT order type, was {orde
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d9a59c09a55efd53.
Report an issue: GitHub.