nautechsystems/nautilus_trader · error

Bids length mismatch: expected {DEPTH10_LEN}, was {}

Error message

Bids length mismatch: expected {DEPTH10_LEN}, was {}

What it means

BitMEX `orderBook10` depth messages must contain exactly DEPTH10_LEN (25) bid levels; the adapter converts the parsed bid vector into a fixed-size `[BookOrder; DEPTH10_LEN]` array. `Vec::try_into` fails when the count differs, and this error reports the actual length received. The fixed array is required by the downstream order book data model.

Source

Thrown at crates/adapters/bitmex/src/websocket/parse.rs:329

        bids.push(bid_order);
        bid_counts[i] = 1;
    }

    for (i, level) in msg.asks.iter().enumerate() {
        let ask_order = BookOrder::new(
            OrderSide::Sell,
            Price::new(level[0], price_precision),
            parse_fractional_quantity(level[1], instrument),
            0,
        );

        asks.push(ask_order);
        ask_counts[i] = 1;
    }

    let bids: [BookOrder; DEPTH10_LEN] = bids.try_into().map_err(|v: Vec<BookOrder>| {
        anyhow::anyhow!(
            "Bids length mismatch: expected {DEPTH10_LEN}, was {}",
            v.len()
        )
    })?;
    let asks: [BookOrder; DEPTH10_LEN] = asks.try_into().map_err(|v: Vec<BookOrder>| {
        anyhow::anyhow!(
            "Asks length mismatch: expected {DEPTH10_LEN}, was {}",
            v.len()
        )
    })?;

    let ts_event = UnixNanos::from(msg.timestamp);

    Ok(OrderBookDepth10::new(
        instrument_id,
        bids,
        asks,
        bid_counts,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log the offending message and confirm the symbol/book actually has fewer than 25 levels; pad the top-of-book by replicating or treat as partial depth if supported.
  2. Ensure the message being parsed is genuinely an `orderBook10` snapshot and not another depth message type.
  3. Update test fixtures to include exactly 25 bid entries.
  4. If BitMEX changed the payload, adjust the parser to validate/normalize to DEPTH10_LEN before conversion.

Example fix

// before
// fixture with only 3 bid levels fed to parse_book10_msg
let bids = vec![level1, level2, level3];
// after
let bids = pad_to_depth10(bids); // ensure exactly DEPTH10_LEN entries before parsing
// or filter: if bids.len() != DEPTH10_LEN { skip/update incremental book instead }
Defensive patterns

Strategy: validation

Validate before calling

if bids.len() != DEPTH10_LEN {
    return Err(anyhow::anyhow!("bids must have exactly {DEPTH10_LEN} levels, got {}", bids.len()));
}

Type guard

fn is_full_depth(v: &[BookOrder]) -> bool { v.len() == DEPTH10_LEN }

Try / catch

match parse_book10_msg(&msg) {
    Ok(book) => book,
    Err(e) if e.to_string().contains("length mismatch") => { log::debug!("shallow/invalid book10 skipped: {e}"); fallback_to_l2(msg); }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `parse_book10_msg` at crates/adapters/bitmex/src/websocket/parse.rs:329 receives an `orderBook10` message whose `bids` array has fewer or more than 25 entries — e.g. a thin book on a new/illiquid symbol, or a malformed/truncated message.

Common situations: Illiquid or new symbols where BitMEX sends fewer than 25 levels; test fixtures with short bid arrays; BitMEX changing depth payload semantics; feeding an `orderBookL2` style message into the book10 parser.

Related errors


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