{"record":{"id":"fbb5ec04a0bfdfa6","repo":"nautechsystems/nautilus_trader","slug":"cancel-algo-order-failed","errorCode":null,"errorMessage":"cancel algo order failed","messagePattern":"cancel algo order failed","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/execution.rs","lineNumber":1073,"sourceCode":"\n        self.spawn_task(\"cancel_algo_order\", async move {\n            let responses = if is_advance {\n                http_client.cancel_advance_algo_orders(vec![request]).await\n            } else {\n                http_client.cancel_algo_orders(vec![request]).await\n            };\n\n            match responses {\n                Err(e) => {\n                    emit_cancel_failure(\n                        classify_okx_http_failure(&e),\n                        Some((&emitter, clock)),\n                        command.client_order_id,\n                        command.instrument_id,\n                        command.strategy_id,\n                        command.venue_order_id,\n                    );\n                    return Err(anyhow::Error::new(e).context(\"cancel algo order failed\"));\n                }\n                Ok(resps) => {\n                    if let Some((code, msg)) = resps.first().and_then(|r| {\n                        r.s_code.as_deref().and_then(|code| {\n                            (code != OKX_SUCCESS_CODE)\n                                .then_some((code, r.s_msg.as_deref().unwrap_or(\"unknown\")))\n                        })\n                    }) {\n                        let reason =\n                            format!(\"cancel-algo-order-rejected: s_code={code}, s_msg={msg}\");\n                        let failure = classify_okx_venue_code(code, reason.clone());\n                        let is_rejected = matches!(failure, CommandFailure::VenueRejected(_));\n                        emit_cancel_failure(\n                            failure,\n                            Some((&emitter, clock)),\n                            command.client_order_id,\n                            command.instrument_id,\n                            command.strategy_id,","sourceCodeStart":1055,"sourceCodeEnd":1091,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/execution.rs#L1055-L1091","documentation":"Canceling an algo (conditional/trigger) order over the OKX REST algo-cancel endpoint failed. This fires both when the HTTP request itself errors and, as a bail, when OKX returns a per-item s_code other than the success code — in which case the message is 'cancel-algo-order-rejected: s_code=..., s_msg=...'. A cancel failure event is emitted to the strategy in the transport-error case.","triggerScenarios":"cancel_order routed to AlgoHttp; http_client.cancel_algo_orders/cancel_advance_algo_orders returned Err, or the first response item carried s_code != OKX_SUCCESS_CODE (e.g. algo order already triggered/canceled, wrong algo_id, order belongs to another instrument).","commonSituations":"Canceling a trigger order that already fired into a live order (algo id no longer cancelable); stale venue_order_id after restart; mixing advance (TWAP/OCO-style) and regular algo orders — the adapter picks the endpoint from the cached order type, and a cache miss defaults to the regular endpoint.","solutions":["Read the s_code/s_msg in the rejection (or chained HTTP error); if 51400/51401-style 'order not exist' or 'already canceled', treat as no-op and let reconciliation settle state.","Ensure the algo order's venue_order_id (algo_id) is current — reconcile after restart before canceling.","Verify the order type in the cache matches what was submitted (advance algo vs regular algo) so the correct endpoint is used.","Confirm credentials/network if the failure is a transport error rather than a venue rejection."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the algo order is still cancelable and its algo_id is known\nlet cancelable = cache.order(&cid)\n    .map(|o| matches!(o.order_type(), OrderType::StopLimit | OrderType::StopMarket | OrderType::TrailingStopMarket) && !o.is_closed())\n    .unwrap_or(false);\nif !cancelable { return; }","typeGuard":null,"tryCatchPattern":"// Parse the rejection reason before deciding to retry\nif let Err(e) = trader.cancel_order(cid) {\n    let msg = format!(\"{e:#}\");\n    if msg.contains(\"cancel-algo-order-rejected\") && (msg.contains(\"51400\") || msg.contains(\"already\")) {\n        // order gone/triggered: no retry needed\n    }\n}","preventionTips":["Reconcile after restart so algo_id (venue_order_id) bindings are current.","Remember triggered algo orders become regular orders — cancel the child order instead.","Verify the cached order type matches the submitted algo class (regular vs advance).","Log s_code/s_msg from cancel responses to distinguish rejection classes."],"tags":["okx","http","algo-orders","order-cancel","venue-rejection"],"backgroundTag":"api-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"}