{"record":{"id":"fa89352bff8511c7","repo":"nautechsystems/nautilus_trader","slug":"reason-fa8935","errorCode":null,"errorMessage":"{reason}","messagePattern":"\\{reason\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/execution.rs","lineNumber":1096,"sourceCode":"                            (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,\n                            command.venue_order_id,\n                        );\n\n                        if is_rejected {\n                            anyhow::bail!(\"{reason}\");\n                        }\n                    }\n                }\n            }\n\n            Ok(())\n        });\n    }\n\n    fn mass_cancel_instrument(&self, instrument_id: InstrumentId) {\n        if is_spread_instrument(instrument_id) {\n            let http_client = self.http_client.clone();\n            self.spawn_task(\"mass_cancel_orders_http\", async move {\n                if let Err(e) = http_client.cancel_all_orders(instrument_id).await {\n                    log_mass_cancel_failure(classify_okx_http_failure(&e), instrument_id);\n                    return Err(anyhow::Error::new(e).context(\"mass cancel orders failed\"));\n                }\n                Ok(())","sourceCodeStart":1078,"sourceCodeEnd":1114,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/execution.rs#L1078-L1114","documentation":"During `cancel_algo_order` (invoked from `cancel_order`), the adapter's HTTP cancel path reports a rejection reason for the algo-order cancel request; if `is_rejected` is true, the adapter aborts with the venue-provided `{reason}` as the error message. This means OKX itself refused the algo cancel, not the adapter.","triggerScenarios":"Calling `cancel_order` for an algo order where the OKX cancel response marks the result as rejected; the raw OKX reason string (e.g. order already filled/canceled, invalid algo ID, order not found) becomes the error text.","commonSituations":"Race condition where the trigger order fires (fills) just before the cancel arrives; canceling with a stale `venue_order_id` after a reconnect; duplicate cancel requests.","solutions":["Read the embedded `{reason}` text — it is OKX's own rejection message (commonly 'order already canceled' or 'order has been filled').","Check the order's current state in the cache before issuing a cancel; skip cancel if already closed/filled.","Make cancel handling idempotent: treat 'already canceled/filled' rejections as success in your reconciliation logic.","Retry with a fresh `venue_order_id` if the ID was stale after a session re-establishment."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if let Some(order) = cache.order_for_venue(&venue_order_id) {\n    if order.is_closed() {\n        return Ok(()); // nothing to cancel\n    }\n}","typeGuard":null,"tryCatchPattern":"match client.cancel_order(cmd) {\n    Err(e) if e.to_string().contains(\"already canceled\") || e.to_string().contains(\"filled\") => {\n        log::warn!(\"cancel rejected as already closed: {e}\"); // treat as idempotent success\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Check cached order state before issuing algo cancels.","Make cancel flows idempotent — duplicate or late cancels are normal.","Log the full venue reason string; it identifies whether the order filled or was already canceled."],"tags":["okx","cancel-order","algo-order","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"}