nautechsystems/nautilus_trader · error · anyhow::Error

Failed to parse price (fill_px='{}', avg_px='{}', px='{}'):

Error message

Failed to parse price (fill_px='{}', avg_px='{}', px='{}'): {}

What it means

While building an OrderFilled report for a regular (non-spread) OKX order update, the adapter picks the fill price from fill_px, else avg_px, else px, and parses it with the instrument's price precision. This error is thrown when none of those price strings parse into a valid Price at the instrument's precision, so the fill report cannot be constructed.

Source

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

        TradeId::new(&synthetic)
    } else {
        TradeId::new(&msg.trade_id)
    };

    let order_side = OrderSide::from(msg.side);

    let price_precision = instrument.price_precision();
    let size_precision = instrument.size_precision();

    let price_str = if !msg.fill_px.is_empty() {
        &msg.fill_px
    } else if !msg.avg_px.is_empty() {
        &msg.avg_px
    } else {
        &msg.px
    };
    let last_px = parse_price(price_str, price_precision).map_err(|e| {
        anyhow::anyhow!(
            "Failed to parse price (fill_px='{}', avg_px='{}', px='{}'): {}",
            msg.fill_px,
            msg.avg_px,
            msg.px,
            e
        )
    })?;

    // OKX provides fillSz (incremental fill) or accFillSz (cumulative total)
    // If fillSz is provided, use it directly as the incremental fill quantity
    let last_qty = if !msg.fill_sz.is_empty() && msg.fill_sz != "0" {
        parse_quantity(&msg.fill_sz, size_precision)
            .map_err(|e| anyhow::anyhow!("Failed to parse fill_sz='{}': {e}", msg.fill_sz,))?
    } else if let Some(ref acc_fill_sz) = msg.acc_fill_sz {
        // If fillSz is missing but accFillSz is available, calculate incremental fill
        if !acc_fill_sz.is_empty() && acc_fill_sz != "0" {
            let current_filled = parse_quantity(acc_fill_sz, size_precision).map_err(|e| {
                anyhow::anyhow!("Failed to parse acc_fill_sz='{acc_fill_sz}': {e}",)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check which of fill_px/avg_px/px appeared in the message (the error prints all three) and whether the value is numeric and non-negative.
  2. Reload the instrument definition so price_precision matches OKX's current tickSz for the instrument.
  3. If the order never traded (e.g. canceled with empty fill_px), ensure only filled order updates reach parse_fill_report.
  4. Update the adapter if OKX changed the order push schema.

Example fix

// before: stale tickSz => price_precision rejects '112345.5'
// after: refresh instrument defs before subscribing
let instrument = await provider.instrument(inst_id).await?; // fresh tickSz
Defensive patterns

Strategy: validation

Validate before calling

// Rust: validate the chosen price string before the adapter does
fn is_parseable_price(fill_px: &str, avg_px: &str, px: &str, precision: u32) -> bool {
    let s = if !fill_px.is_empty() { fill_px } else if !avg_px.is_empty() { avg_px } else { px };
    rust_decimal::Decimal::from_str(s).map(|d| d.scale() as u32 <= precision).unwrap_or(false)
}

Try / catch

match parse_fill_report(&msg, ...) {
    Ok(r) => emit(r),
    Err(e) => { log::warn!("fill price parse failed: {e}"); resync_fills_via_rest(&msg.inst_id); }
}

Prevention

When it happens

Trigger: parse_fill_report (called from parse_order_event / parse_order_msg) receives an OKX 'orders' channel message where the chosen price field (fill_px or avg_px or px) is non-empty but fails parse_price — e.g. empty string when other fields are empty too, non-numeric text, negative price, or more decimals than price_precision.

Common situations: Canceled orders carrying empty price fields; a stale instrument definition whose price_precision (tickSz) is tighter than the received price; OKX API format changes; corrupted test fixtures.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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