nautechsystems/nautilus_trader · error · anyhow::Error
Unsupported OKX order status: {e}
Error message
Unsupported OKX order status: {e} What it means
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.
Source
Thrown at crates/adapters/okx/src/websocket/parse.rs:1759
OrderType::StopLimit
}
}
OKXOrderType::Fok | OKXOrderType::Ioc | OKXOrderType::OptimalLimitIoc => {
determine_order_type_with_alt(
okx_order_type,
&msg.px,
msg.px_vol.as_deref().unwrap_or(""),
msg.px_usd.as_deref().unwrap_or(""),
)?
}
other => other
.try_into()
.map_err(|e| anyhow::anyhow!("Unsupported OKX order type: {e}"))?,
};
let order_status: OrderStatus = msg
.state
.try_into()
.map_err(|e| anyhow::anyhow!("Unsupported OKX order status: {e}"))?;
let time_in_force = match okx_order_type {
OKXOrderType::Fok | OKXOrderType::OpFok => TimeInForce::Fok,
OKXOrderType::Ioc | OKXOrderType::OptimalLimitIoc => TimeInForce::Ioc,
_ => TimeInForce::Gtc,
};
let size_precision = instrument.size_precision();
// Parse quantities based on target currency
// OKX always returns acc_fill_sz in base currency, but sz depends on tgt_ccy
// Determine if this is a quote-quantity order
// Method 1: Explicit tgt_ccy field set to QuoteCcy
let is_quote_qty_explicit = msg.tgt_ccy == Some(OKXTargetCurrency::QuoteCcy);
// Method 2: Use OKX defaults when tgt_ccy is None (old orders or missing field)
// OKX API defaults for SPOT market orders: BUY orders use quote_ccy, SELL orders use base_ccyView on GitHub (pinned to 18893faf8b)
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.
Example fix
// before (parse.rs:1756)
let order_status: OrderStatus = msg.state.try_into()
.map_err(|e| anyhow::anyhow!("Unsupported OKX order status: {e}"))?;
// after (add mapping in the TryFrom<OKXOrderStatus> for OrderStatus impl)
OKXOrderStatus::MmpCanceled => Ok(OrderStatus::Canceled), // map the newly seen state Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: check the state maps before parsing the full report
fn is_supported_order_state(s: &OKXOrderStatus) -> bool {
OrderStatus::try_from(*s).is_ok()
} Type guard
fn supported_order_status(s: &OKXOrderStatus) -> Option<OrderStatus> {
OrderStatus::try_from(*s).ok()
} Try / catch
match parse_order_status_report(&msg, &instrument, account_id, ts_init) {
Ok(report) => handle(report),
Err(e) if e.to_string().contains("Unsupported OKX order status") => {
tracing::warn!(ord_id = %msg.ord_id, state = ?msg.state, "skipping order with unsupported state");
}
Err(e) => return Err(e),
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unsupported OKX order type: {e}
- Unsupported trigger type for Kraken Spot WS: {other:?} (only
- Unsupported time in force: {time_in_force:?}
- Invalid `BarSpecification` for channel, was {bar_spec}
- Invalid funding_rate value: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d3fd3712acdac635.
Report an issue: GitHub.