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

  1. Log order.state and ord_id to capture the unrecognized value
  2. Upgrade the nautilus-adapters/OKX crate to a version supporting the new OKX state
  3. Patch the OKXOrderStatus->OrderStatus TryFrom impl to map or gracefully ignore the new state
  4. 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

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


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