nautechsystems/nautilus_trader · error

Missing sz for algo order {}

Error message

Missing sz for algo order {}

What it means

An OKX algo order message carries its size in sz. If sz is absent/empty, and the message also lacks any stop-loss/take-profit trigger fields (which would imply zero size), the parser cannot construct a quantity and bails with the algo_id in the message.

Source

Thrown at crates/adapters/okx/src/websocket/parse.rs:1714

    }
}

fn parse_algo_order_quantity(
    msg: &OKXAlgoOrderMsg,
    instrument: &InstrumentAny,
) -> anyhow::Result<Quantity> {
    if !msg.sz.is_empty() {
        return parse_quantity(msg.sz.as_str(), instrument.size_precision());
    }

    if !msg.close_fraction.is_empty()
        || !msg.sl_trigger_px.is_empty()
        || !msg.tp_trigger_px.is_empty()
    {
        return Ok(Quantity::zero(instrument.size_precision()));
    }

    anyhow::bail!("Missing sz for algo order {}", msg.algo_id)
}

/// Parses an OKX order message into a Nautilus order status report.
///
/// # Errors
///
/// Returns an error if order metadata or numeric values cannot be parsed.
pub fn parse_order_status_report(
    msg: &OKXOrderMsg,
    instrument: &InstrumentAny,
    account_id: AccountId,
    ts_init: UnixNanos,
) -> anyhow::Result<OrderStatusReport> {
    let client_order_id =
        parse_parent_client_order_id(msg.algo_cl_ord_id.as_deref(), &msg.cl_ord_id);
    let venue_order_id = VenueOrderId::new(msg.ord_id);
    let order_side = OrderSide::from(msg.side);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check whether the specific algo_id's message stream omits sz and whether your order type requires it
  2. Include sz when placing the algo order so all updates carry it
  3. Handle/prefilter these updates before parse_algo_order_quantity, or map messages without sz to a status-only event

Example fix

// before
// sz empty and no tp/sl triggers -> bail
// after: treat as size-less status update
if msg.sz.is_none() {
    return Ok(Quantity::zero(instrument.size_precision()));
}
Defensive patterns

Strategy: type-guard

Validate before calling

fn has_size(msg: &OKXAlgoOrderMsg) -> bool {
    msg.sz.as_deref().map_or(false, |s| !s.is_empty())
        || !msg.sl_trigger_px.is_empty()
        || !msg.tp_trigger_px.is_empty()
}

Type guard

fn is_fill_bearing(msg: &OKXAlgoOrderMsg) -> bool { msg.sz.as_deref().map_or(false, |s| !s.is_empty()) }

Try / catch

if !is_fill_bearing(&msg) { return Ok(None); } // skip status-only algo updates

Prevention

When it happens

Trigger: Receiving an algo order update where msg.sz is None/empty and none of sl_trigger_px / tp_trigger_px / sl_trigger_px-ish fields are set, e.g. an amend or cancel push that strips sz.

Common situations: OKX pushing state-change updates for algo orders without full fields; partial snapshots; adapter subscribed to algo channel for order types it can't fully parse.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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