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_ccy

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the raw msg.state value on the failing message to identify the unmapped state.
  2. Add the missing OKXOrderStatus -> OrderStatus mapping in the okx adapter's TryFrom impl.
  3. Upgrade the nautilus okx adapter to a release that includes mappings for newer OKX order states.
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/d3fd3712acdac635. Report an issue: GitHub.