{"record":{"id":"ebc458ce80ff163c","repo":"nautechsystems/nautilus_trader","slug":"failed-to-batch-cancel-orders","errorCode":null,"errorMessage":"failed to batch cancel orders","messagePattern":"failed to batch cancel orders","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/cancellations.rs","lineNumber":504,"sourceCode":"            match submitter.cancel_orders(&order_id_refs).await {\n                Ok(response) => {\n                    for (venue_id_str, order) in &venue_to_order {\n                        let vid = VenueOrderId::from(venue_id_str.as_str());\n                        process_cancel_result(&response, venue_id_str, order, vid, &emitter, clock);\n                    }\n\n                    log::debug!(\"Batch canceled {} orders\", response.canceled.len());\n                    Ok(())\n                }\n                Err(e) => {\n                    let orders: Vec<(VenueOrderId, OrderAny)> = venue_to_order\n                        .iter()\n                        .map(|(venue_id_str, order)| {\n                            (VenueOrderId::from(venue_id_str.as_str()), order.clone())\n                        })\n                        .collect();\n                    apply_cancel_http_failure(&e, &orders, &emitter, clock);\n                    Err(anyhow::Error::new(e).context(\"failed to batch cancel orders\"))\n                }\n            }\n        });\n    }\n\n    fn cancel_venue_order_id(&self, order: &OrderAny) -> Option<VenueOrderId> {\n        self.order_contexts\n            .venue_order_id(&order.client_order_id())\n            .or_else(|| order.venue_order_id())\n            .or_else(|| {\n                self.core\n                    .cache()\n                    .venue_order_id(&order.client_order_id())\n                    .copied()\n            })\n    }\n}\n","sourceCodeStart":486,"sourceCodeEnd":522,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/cancellations.rs#L486-L522","documentation":"Polymarket's batch_cancel_orders_command submits a batch of order cancels to the CLOB API. When the batch HTTP call returns Err, each order is marked failed via apply_cancel_http_failure and the task returns \"failed to batch cancel orders\". The canceled/not_canceled split in the response is the success path; this is the outright call-failure path.","triggerScenarios":"Calling batch_cancel_orders with client_order_ids when the CLOB batch endpoint errors: authentication/nonce failure, malformed batch payload, network error, or venue rejection of the whole request.","commonSituations":"Batch containing stale or already-terminal order ids; credential desync after restart; exceeding Polymarket batch size limits; transient CLOB outage during volatile markets.","solutions":["Inspect the underlying error for the CLOB HTTP status and error payload.","Pre-filter the batch to live, open orders only; drop already-canceled/filled ids.","Verify API credentials and signer nonce are current.","Retry the batch with backoff; on repeated failure, split into smaller batches or per-order cancels.","Confirm batch size is within Polymarket's API limits."],"exampleFix":"// before\nlet ids: Vec<_> = all_orders.iter().map(|o| o.client_order_id()).collect();\nclient.batch_cancel_orders(&ids)?;\n// after\nlet ids: Vec<_> = all_orders.iter()\n    .filter(|o| o.status() == OrderStatus::Accepted)\n    .map(|o| o.client_order_id()).collect();\nfor chunk in ids.chunks(50) { client.batch_cancel_orders(chunk)?; }","handlingStrategy":"validation","validationCode":"// only live orders, within batch limits\nlet ids: Vec<_> = orders.iter()\n    .filter(|o| o.status() == OrderStatus::Accepted)\n    .map(|o| o.client_order_id()).collect();\nassert!(ids.len() <= MAX_BATCH, \"batch too large\");","typeGuard":null,"tryCatchPattern":"match client.batch_cancel_orders(&ids) {\n    Ok(()) => {}\n    Err(e) => {\n        warn!(\"batch cancel failed: {e}; splitting batch\");\n        for half in ids.chunks(ids.len().div_ceil(2).max(1)) {\n            retry_with_backoff(|| client.batch_cancel_orders(half));\n        }\n    }\n}","preventionTips":["Pre-filter batches to open, live orders","Keep batches small and within venue limits","Verify credentials/nonce freshness before batch calls","Retry with backoff; escalate to per-order cancels on repeated failure"],"tags":["polymarket","batch-cancel","http","clob"],"backgroundTag":"http-error-response","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"}