{"record":{"id":"d3fd3712acdac635","repo":"nautechsystems/nautilus_trader","slug":"unsupported-okx-order-status-e-d3fd37","errorCode":null,"errorMessage":"Unsupported OKX order status: {e}","messagePattern":"Unsupported OKX order status: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/websocket/parse.rs","lineNumber":1759,"sourceCode":"                OrderType::StopLimit\n            }\n        }\n        OKXOrderType::Fok | OKXOrderType::Ioc | OKXOrderType::OptimalLimitIoc => {\n            determine_order_type_with_alt(\n                okx_order_type,\n                &msg.px,\n                msg.px_vol.as_deref().unwrap_or(\"\"),\n                msg.px_usd.as_deref().unwrap_or(\"\"),\n            )?\n        }\n        other => other\n            .try_into()\n            .map_err(|e| anyhow::anyhow!(\"Unsupported OKX order type: {e}\"))?,\n    };\n    let order_status: OrderStatus = msg\n        .state\n        .try_into()\n        .map_err(|e| anyhow::anyhow!(\"Unsupported OKX order status: {e}\"))?;\n\n    let time_in_force = match okx_order_type {\n        OKXOrderType::Fok | OKXOrderType::OpFok => TimeInForce::Fok,\n        OKXOrderType::Ioc | OKXOrderType::OptimalLimitIoc => TimeInForce::Ioc,\n        _ => TimeInForce::Gtc,\n    };\n\n    let size_precision = instrument.size_precision();\n\n    // Parse quantities based on target currency\n    // OKX always returns acc_fill_sz in base currency, but sz depends on tgt_ccy\n\n    // Determine if this is a quote-quantity order\n    // Method 1: Explicit tgt_ccy field set to QuoteCcy\n    let is_quote_qty_explicit = msg.tgt_ccy == Some(OKXTargetCurrency::QuoteCcy);\n\n    // Method 2: Use OKX defaults when tgt_ccy is None (old orders or missing field)\n    // OKX API defaults for SPOT market orders: BUY orders use quote_ccy, SELL orders use base_ccy","sourceCodeStart":1741,"sourceCodeEnd":1777,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/websocket/parse.rs#L1741-L1777","documentation":"After resolving the order type, parse_order_status_report converts the OKX order `state` field into a Nautilus OrderStatus via TryFrom. If the state value has no mapping, this error is raised. It means the adapter received an OKX order state (e.g. a newly added state string) that it cannot translate into a Nautilus order status.","triggerScenarios":"An OKX orders-channel update whose `state` deserializes to an OKXOrderStatus variant with no `TryInto<OrderStatus>` mapping (any state outside the recognized set such as live, partially_filled, filled, canceled). Produced on every parse path (parse_order_event, parse_order_msg) for that message, and by tests feeding synthetic states.","commonSituations":"OKX introduces a new order state in an API update (e.g. mmp_canceled or a regional variant) while the adapter is outdated; an instrument class whose lifecycle includes states the adapter never mapped; replaying historical data captured with a newer API than the adapter supports.","solutions":["Inspect the raw msg.state value on the failing message to identify the unmapped state.","Add the missing OKXOrderStatus -> OrderStatus mapping in the okx adapter's TryFrom impl.","Upgrade the nautilus okx adapter to a release that includes mappings for newer OKX order states.","Short-term, drop or dead-letter the offending status update so one unknown state does not stall the reconciliation stream."],"exampleFix":"// before (parse.rs:1756)\nlet order_status: OrderStatus = msg.state.try_into()\n    .map_err(|e| anyhow::anyhow!(\"Unsupported OKX order status: {e}\"))?;\n\n// after (add mapping in the TryFrom<OKXOrderStatus> for OrderStatus impl)\nOKXOrderStatus::MmpCanceled => Ok(OrderStatus::Canceled), // map the newly seen state","handlingStrategy":"try-catch","validationCode":"// Rust: check the state maps before parsing the full report\nfn is_supported_order_state(s: &OKXOrderStatus) -> bool {\n    OrderStatus::try_from(*s).is_ok()\n}","typeGuard":"fn supported_order_status(s: &OKXOrderStatus) -> Option<OrderStatus> {\n    OrderStatus::try_from(*s).ok()\n}","tryCatchPattern":"match parse_order_status_report(&msg, &instrument, account_id, ts_init) {\n    Ok(report) => handle(report),\n    Err(e) if e.to_string().contains(\"Unsupported OKX order status\") => {\n        tracing::warn!(ord_id = %msg.ord_id, state = ?msg.state, \"skipping order with unsupported state\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Subscribe to OKX API changelog and update the OKXOrderStatus enum when new states ship.","Use serde deny_unknown_fields or log-on-unknown for state deserialization to surface new values immediately.","Test reconciliation against recorded fixtures that include all documented OKX order states.","Dead-letter unknown states rather than letting one message break the whole status stream."],"tags":["rust","okx","websocket","order-parsing","unsupported-enum-value"],"backgroundTag":"unsupported-enum-value","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"}