nautechsystems/nautilus_trader · error · anyhow::Error
venue_order_ids cannot be empty
Error message
venue_order_ids cannot be empty
What it means
This error is raised by the BitMEX HTTP adapter's cancel_orders method when the caller passes Some(venue_order_ids) but the collection is empty. BitMEX's cancel order endpoint requires at least one order identifier, and an empty 'orderID' list would produce a malformed request. The bail stops the request before it is sent to the venue.
Source
Thrown at crates/adapters/bitmex/src/http/client.rs:1851
/// Returns an error if:
/// - Credentials are missing.
/// - The request fails.
/// - The order doesn't exist.
/// - The API returns an error.
pub async fn cancel_orders(
&self,
instrument_id: InstrumentId,
client_order_ids: Option<Vec<ClientOrderId>>,
venue_order_ids: Option<Vec<VenueOrderId>>,
) -> anyhow::Result<Vec<OrderStatusReport>> {
let mut params = super::query::DeleteOrderParamsBuilder::default();
params.text(NAUTILUS_TRADER);
// BitMEX API requires either client order IDs or venue order IDs, not both
// Prioritize venue order IDs if both are provided
if let Some(venue_order_ids) = venue_order_ids {
if venue_order_ids.is_empty() {
anyhow::bail!("venue_order_ids cannot be empty");
}
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 {View on GitHub (pinned to 18893faf8b)
Solutions
- Only wrap the venue order ID collection in Some when it contains at least one ID
- Check venue_order_ids.is_empty() at the call site before invoking cancel_orders
- If no venue order IDs exist, pass None and use client_order_ids instead, or skip the cancel call entirely
Example fix
// before
let ids: Vec<VenueOrderId> = working.iter().map(|o| o.venue_order_id.clone()).collect();
client.cancel_orders(None, Some(ids)).await?;
// after
let ids: Vec<VenueOrderId> = working.iter().map(|o| o.venue_order_id.clone()).collect();
if ids.is_empty() { return Ok(()); }
client.cancel_orders(None, Some(ids)).await?; Defensive patterns
Strategy: validation
Validate before calling
if let Some(ids) = &venue_order_ids {
if ids.is_empty() { return Err(anyhow!("venue_order_ids must not be empty")); }
}
client.cancel_orders(client_order_ids, venue_order_ids).await?; Type guard
fn has_ids(ids: &Option<Vec<VenueOrderId>>) -> bool {
ids.as_ref().is_some_and(|v| !v.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("cannot be empty") => { /* fix inputs and retry */ }
Err(e) => return Err(e),
} Prevention
- Only wrap ID collections in Some when non-empty
- Treat None vs empty Vec as distinct states in your order-management code
- Add unit tests covering empty-list cancel scenarios
When it happens
Trigger: Calling cancel_orders with venue_order_ids=Some(vec![]) — i.e. the Option is set but the Vec contains no IDs. Typically happens when caller code filters or collects order IDs from an empty set of working orders but still wraps the result in Some.
Common situations: Batch-cancel flows where order IDs were gathered from a cached or queried order list that turned out to be empty; code that distinguishes 'not provided' from 'empty list' incorrectly.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- client_order_ids cannot be empty
- `peg_offset_value` requires `peg_price_type`
- Pegged orders only supported for LIMIT order type, was {orde
- BitMEX only supports PRICE trailing offset type, was {offset
- `peg_offset_value` requires `peg_price_type`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/510ce8ece4ada81e.
Report an issue: GitHub.