nautechsystems/nautilus_trader · 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
Bybit identifies orders either by its own orderId or by the client-supplied orderLinkId. The cancel-order request builder requires at least one of them; the adapter bails when both are None because the request would be invalid.
Source
Thrown at crates/adapters/bybit/src/http/client.rs:2704
&self,
account_id: AccountId,
product_type: BybitProductType,
instrument_id: InstrumentId,
client_order_id: Option<ClientOrderId>,
venue_order_id: Option<VenueOrderId>,
) -> anyhow::Result<OrderStatusReport> {
let instrument = self.instrument_from_cache(&instrument_id.symbol)?;
let bybit_symbol = BybitSymbol::new(instrument_id.symbol.as_str())?;
let mut cancel_entry = BybitBatchCancelOrderEntryBuilder::default();
cancel_entry.symbol(bybit_symbol.raw_symbol().to_string());
if let Some(venue_order_id) = venue_order_id {
cancel_entry.order_id(venue_order_id.to_string());
} else if let Some(client_order_id) = client_order_id {
cancel_entry.order_link_id(client_order_id.to_string());
} else {
anyhow::bail!("Either client_order_id or venue_order_id must be provided");
}
let cancel_entry = cancel_entry.build().build_anyhow()?;
let mut params = BybitCancelOrderParamsBuilder::default();
params.category(product_type);
params.order(cancel_entry);
let params = params.build().build_anyhow()?;
let body = serde_json::to_vec(¶ms)?;
let response: BybitPlaceOrderResponse = self
.inner
.send_request::<_, ()>(Method::POST, "/v5/order/cancel", None, Some(body), true)
.await?;
let order_id = response
.resultView on GitHub (pinned to 18893faf8b)
Solutions
- Always supply the venue_order_id if the order was acknowledged by the venue
- Otherwise supply the client_order_id used at submission
- Add a caller-side check that at least one identifier is Some before invoking the client
Example fix
// before client.cancel_order(product_type, symbol, None, None).await?; // after client.cancel_order(product_type, symbol, Some(venue_order_id), None).await?
Defensive patterns
Strategy: validation
Validate before calling
anyhow::ensure!(venue_order_id.is_some() || client_order_id.is_some(), "cancel needs venue_order_id or client_order_id");
Type guard
fn has_order_id(v: &Option<VenueOrderId>, c: &Option<ClientOrderId>) -> bool { v.is_some() || c.is_some() } Try / catch
match client.cancel_order(pt, symbol, venue_id, client_id).await {
Err(e) if e.to_string().contains("must be provided") => { /* resolve identifier from cache and retry */ }
other => other?,
} Prevention
- Store the client_order_id for every submitted order
- Update venue_order_id from order accepted events
- Never construct cancel calls with both identifiers None
When it happens
Trigger: Calling cancel_order on the Bybit HTTP client with both venue_order_id and client_order_id as None.
Common situations: A caller that lost track of the order identifiers, e.g. passing through an event where neither ID was populated; constructing cancel requests programmatically with unwrapped-then-dropped Option values.
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
- cancel order rejected: {reason}
- Either client_order_id or venue_order_id must be provided fo
- Either client_order_id or venue_order_id must be provided
- Batch cancel limit is {endpoint_limit} orders for {product_t
- WS cancel order failed: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2bbe148dd423c12e.
Report an issue: GitHub.