{"record":{"id":"510ce8ece4ada81e","repo":"nautechsystems/nautilus_trader","slug":"venue-order-ids-cannot-be-empty","errorCode":null,"errorMessage":"venue_order_ids cannot be empty","messagePattern":"venue_order_ids cannot be empty","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/bitmex/src/http/client.rs","lineNumber":1851,"sourceCode":"    /// Returns an error if:\n    /// - Credentials are missing.\n    /// - The request fails.\n    /// - The order doesn't exist.\n    /// - The API returns an error.\n    pub async fn cancel_orders(\n        &self,\n        instrument_id: InstrumentId,\n        client_order_ids: Option<Vec<ClientOrderId>>,\n        venue_order_ids: Option<Vec<VenueOrderId>>,\n    ) -> anyhow::Result<Vec<OrderStatusReport>> {\n        let mut params = super::query::DeleteOrderParamsBuilder::default();\n        params.text(NAUTILUS_TRADER);\n\n        // BitMEX API requires either client order IDs or venue order IDs, not both\n        // Prioritize venue order IDs if both are provided\n        if let Some(venue_order_ids) = venue_order_ids {\n            if venue_order_ids.is_empty() {\n                anyhow::bail!(\"venue_order_ids cannot be empty\");\n            }\n            params.order_id(\n                venue_order_ids\n                    .iter()\n                    .map(|id| id.to_string())\n                    .collect::<Vec<_>>(),\n            );\n        } else if let Some(client_order_ids) = client_order_ids {\n            if client_order_ids.is_empty() {\n                anyhow::bail!(\"client_order_ids cannot be empty\");\n            }\n            params.cl_ord_id(\n                client_order_ids\n                    .iter()\n                    .map(|id| id.to_string())\n                    .collect::<Vec<_>>(),\n            );\n        } else {","sourceCodeStart":1833,"sourceCodeEnd":1869,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bitmex/src/http/client.rs#L1833-L1869","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nlet ids: Vec<VenueOrderId> = working.iter().map(|o| o.venue_order_id.clone()).collect();\nclient.cancel_orders(None, Some(ids)).await?;\n// after\nlet ids: Vec<VenueOrderId> = working.iter().map(|o| o.venue_order_id.clone()).collect();\nif ids.is_empty() { return Ok(()); }\nclient.cancel_orders(None, Some(ids)).await?;","handlingStrategy":"validation","validationCode":"if let Some(ids) = &venue_order_ids {\n    if ids.is_empty() { return Err(anyhow!(\"venue_order_ids must not be empty\")); }\n}\nclient.cancel_orders(client_order_ids, venue_order_ids).await?;","typeGuard":"fn has_ids(ids: &Option<Vec<VenueOrderId>>) -> bool {\n    ids.as_ref().is_some_and(|v| !v.is_empty())\n}","tryCatchPattern":"match client.cancel_orders(client_order_ids, venue_order_ids).await {\n    Ok(reports) => { /* handle */ }\n    Err(e) if e.to_string().contains(\"cannot be empty\") => { /* fix inputs and retry */ }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["rust","bitmex","validation","empty-argument"],"backgroundTag":"empty-required-field","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}