nautechsystems/nautilus_trader · error

Bids length mismatch: expected

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.

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.

Appendix: 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)