nautechsystems/nautilus_trader · error
Unsupported OKX order status: {e}
Error message
Unsupported OKX order status: {e} What it means
parse_order_status_report converts the OKX order state string via TryInto<OrderStatus>. This error is raised when the state value received from OKX has no mapping to a Nautilus OrderStatus, meaning the adapter encountered an unrecognized or newly introduced OKX order state.
Source
Thrown at crates/adapters/okx/src/common/parse.rs:838
(quantity_dec, filled_qty_dec)
};
// For quote-quantity orders marked as FILLED, adjust quantity to match filled_qty
// to avoid precision mismatches from quote-to-base conversion
let (quantity, filled_qty) = if (is_quote_qty_explicit || is_quote_qty_heuristic)
&& order.state == OKXOrderStatus::Filled
&& filled_qty.is_positive()
{
(filled_qty, filled_qty)
} else {
(quantity, filled_qty)
};
let order_side = OrderSide::from(order.side);
let order_status: OrderStatus = order
.state
.try_into()
.map_err(|e| anyhow::anyhow!("Unsupported OKX order status: {e}"))?;
let time_in_force = match okx_ord_type {
OKXOrderType::Fok | OKXOrderType::OpFok => TimeInForce::Fok,
OKXOrderType::Ioc | OKXOrderType::OptimalLimitIoc => TimeInForce::Ioc,
_ => TimeInForce::Gtc,
};
let client_order_id = parse_parent_client_order_id(
order.algo_cl_ord_id.as_ref().map(Ustr::as_str),
order.cl_ord_id.as_str(),
);
let mut linked_ids = Vec::new();
if let Some(attach_algo_cl_ord_id) = order
.attach_algo_cl_ord_id
.as_ref()
.filter(|value| !value.as_str().is_empty())
{
let attach_client_id = ClientOrderId::new(attach_algo_cl_ord_id.as_str());View on GitHub (pinned to 18893faf8b)
Solutions
- Log order.state and ord_id to capture the unrecognized value
- Upgrade the nautilus-adapters/OKX crate to a version supporting the new OKX state
- Patch the OKXOrderStatus->OrderStatus TryFrom impl to map or gracefully ignore the new state
- Check for middleware or recorded fixtures injecting non-standard state strings
Example fix
// before
let status: OrderStatus = order.state.try_into().map_err(|e| anyhow!("Unsupported OKX order status: {e}"))?;
// after
let status = match OrderStatus::try_from(order.state) {
Ok(s) => s,
Err(e) => { log::warn!("Skipping order {} with unknown state '{}': {e}", order.ord_id, order.state); return Ok(None); }
}; Defensive patterns
Strategy: try-catch
Validate before calling
fn is_supported_state(state: OKXOrderStatus) -> bool {
matches!(state, OKXOrderStatus::Live | OKXOrderStatus::PartiallyFilled | OKXOrderStatus::Filled | OKXOrderStatus::Canceled)
} // adjust to the exact mapped set in your adapter version Type guard
fn to_order_status(state: OKXOrderStatus) -> Option<OrderStatus> { OrderStatus::try_from(state).ok() } Try / catch
match parse_order_status_report(&order, &instrument, ts_init) {
Ok(r) => handle(r),
Err(e) if e.to_string().contains("Unsupported OKX order status") => { log::warn!("unknown state '{}' for {}: {e}", order.state, order.ord_id); Ok(None) }
Err(e) => Err(e),
} Prevention
- Subscribe to OKX API changelogs for new order states
- Upgrade the adapter when OKX introduces new statuses
- Never fabricate state values in fixtures/mocks
- Handle unknown states by skipping and logging, not crashing the stream
When it happens
Trigger: order.state is a value outside the mapped set (e.g. a new OKX status like a novel state string added by OKX, or a corrupted/unexpected value in the payload) passed through TryInto<OrderStatus>.
Common situations: OKX introducing new order states not yet supported by the installed adapter version; typo'd or synthetic state values in test fixtures/mocks; proxy layers rewriting payloads; using an outdated adapter against the current OKX API.
Related errors
- Unknown position currency '{pos_ccy}' for instrument {instru
- Invalid timeframe for `BarSpecification`, was {timeframe}
- Failed to create quantity from filled_sz: {e}
- Failed to create price from limit_px: {e}
- missing fee
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d5bb793774335102.
Report an issue: GitHub.