{"record":{"id":"89dea5ae496148e9","repo":"nautechsystems/nautilus_trader","slug":"batch-cancel-limit-is-endpoint-limit-orders-for","errorCode":null,"errorMessage":"Batch cancel limit is {endpoint_limit} orders for {product_type}","messagePattern":"Batch cancel limit is (.+?) orders for (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/http/client.rs","lineNumber":2841,"sourceCode":"        instrument_ids: Vec<InstrumentId>,\n        client_order_ids: Vec<Option<ClientOrderId>>,\n        venue_order_ids: Vec<Option<VenueOrderId>>,\n    ) -> anyhow::Result<Vec<OrderStatusReport>> {\n        if instrument_ids.len() != client_order_ids.len()\n            || instrument_ids.len() != venue_order_ids.len()\n        {\n            anyhow::bail!(\n                \"instrument_ids, client_order_ids, and venue_order_ids must have the same length\"\n            );\n        }\n\n        if instrument_ids.is_empty() {\n            return Ok(Vec::new());\n        }\n\n        let endpoint_limit = batch_endpoint_limit(product_type);\n        if instrument_ids.len() > endpoint_limit {\n            anyhow::bail!(\n                \"Batch cancel limit is {endpoint_limit} orders for {}\",\n                product_type.as_str()\n            );\n        }\n\n        let mut cancel_entries = Vec::new();\n\n        for ((instrument_id, client_order_id), venue_order_id) in instrument_ids\n            .iter()\n            .zip(client_order_ids.iter())\n            .zip(venue_order_ids.iter())\n        {\n            let bybit_symbol = BybitSymbol::new(instrument_id.symbol.as_str())?;\n            let mut cancel_entry = BybitBatchCancelOrderEntryBuilder::default();\n            cancel_entry.symbol(bybit_symbol.raw_symbol().to_string());\n\n            if let Some(venue_order_id) = venue_order_id {\n                cancel_entry.order_id(venue_order_id.to_string());","sourceCodeStart":2823,"sourceCodeEnd":2859,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/d1527c24afdf475115785557f89a55c3e336c51f/crates/adapters/bybit/src/http/client.rs#L2823-L2859","documentation":"A Bybit batch cancel request exceeded the venue's per-endpoint batch limit for the given product type (spot vs linear/inverse derivatives have different limits, e.g. linear typically caps batch cancels at 10). The request is rejected client-side before being sent.","triggerScenarios":"Calling the batch cancel path (cancel_all via batch endpoint or batch_cancel_orders) on the Bybit HTTP client with more instrument_ids/orders than batch_endpoint_limit(product_type) allows.","commonSituations":"A strategy firing many cancels across instruments during a volatility spike gets bucketed into one oversized batch; migrating from an adapter/version with a higher limit; spot limits applied to derivatives workflows.","solutions":["Chunk the cancels into batches of at most batch_endpoint_limit(product_type) orders per request","Reduce the number of instruments targeted per batch cancel call","Fall back to individual cancel requests for the remainder when chunking is awkward"],"exampleFix":"// before\nlet reports = client.batch_cancel(instrument_ids).await?;\n// after\nlet limit = 10; // batch_endpoint_limit(product_type)\nfor chunk in instrument_ids.chunks(limit) {\n    let reports = client.batch_cancel(chunk.to_vec()).await?;\n}","handlingStrategy":"validation","validationCode":"const LIMIT: usize = 10; // match batch_endpoint_limit(product_type)\nif instrument_ids.len() > LIMIT {\n    anyhow::bail!(\"batch cancel of {} exceeds Bybit limit {LIMIT}; chunk the request\", instrument_ids.len());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always chunk batch cancels by the venue's documented limit","Cache the per-product-type limit instead of assuming one global value","Log batch sizes during high-volatility cancel storms to catch approaching limits"],"tags":["bybit","batch-cancel","rate-limit","execution"],"backgroundTag":"batch-limit-exceeded","analyzedSha":"d1527c24afdf475115785557f89a55c3e336c51f","analyzedAt":"2026-08-27T04:01:12.327Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}