nautechsystems/nautilus_trader · error

instrument_ids, client_order_ids, and venue_order_ids must h

Error message

instrument_ids, client_order_ids, and venue_order_ids must have the same length

What it means

The batch cancel-all-orders path takes three parallel vectors (instrument IDs, client order IDs, venue order IDs) that must be index-aligned. The adapter validates equal lengths up front and bails otherwise, since misaligned vectors would mix identifiers across orders.

Source

Thrown at crates/adapters/bybit/src/http/client.rs:2761

    /// # Errors
    ///
    /// Returns an error if:
    /// - Credentials are missing.
    /// - The request fails.
    /// - Any of the orders don't exist.
    /// - The API returns an error.
    pub async fn batch_cancel_orders(
        &self,
        account_id: AccountId,
        product_type: BybitProductType,
        instrument_ids: Vec<InstrumentId>,
        client_order_ids: Vec<Option<ClientOrderId>>,
        venue_order_ids: Vec<Option<VenueOrderId>>,
    ) -> anyhow::Result<Vec<OrderStatusReport>> {
        if instrument_ids.len() != client_order_ids.len()
            || instrument_ids.len() != venue_order_ids.len()
        {
            anyhow::bail!(
                "instrument_ids, client_order_ids, and venue_order_ids must have the same length"
            );
        }

        if instrument_ids.is_empty() {
            return Ok(Vec::new());
        }

        let call_limit = batch_call_limit(product_type);
        if instrument_ids.len() > call_limit {
            anyhow::bail!(
                "Batch cancel limit is {call_limit} orders for {}",
                product_type.as_str()
            );
        }

        let mut cancel_entries = Vec::new();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Build the three vectors together in a single loop so they always stay the same length
  2. Use Option entries (None) for orders lacking an identifier instead of omitting the element
  3. Validate lengths before calling

Example fix

// before
if let Some(cid) = client_id { client_ids.push(cid); }
venue_ids.push(vid); // lengths diverge
// after
client_ids.push(client_id);
venue_ids.push(vid); // always paired pushes
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(instrument_ids.len() == client_order_ids.len() && instrument_ids.len() == venue_order_ids.len(), "parallel vectors must be same length");

Prevention

When it happens

Trigger: Calling batch_cancel_all_orders with vectors of differing lengths, e.g. filling client_order_ids for some orders but not appending the corresponding None entries to venue_order_ids.

Common situations: Building the three lists in separate loops where skip conditions differ per list; deserializing request data where null entries were dropped from one list.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/84aae30a0ea9bffd. Report an issue: GitHub.