nautechsystems/nautilus_trader · error

Failed to deserialize Books channel data as Vec<OKXBookMsg>

Error message

Failed to deserialize Books channel data as Vec<OKXBookMsg>

What it means

The OKX WebSocket Books channel message could not be deserialized as a Vec<OKXBookMsg>. The parser expects the `data` field to be an array of order book update messages; anything else causes an anyhow bail.

Source

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

                ts_init,
            )?;
            Ok(Some(NautilusWsMessage::Data(data_vec)))
        }
        OKXWsChannel::Books
        | OKXWsChannel::BooksTbt
        | OKXWsChannel::Books5
        | OKXWsChannel::Books50Tbt => {
            if let Ok(book_msgs) = serde_json::from_value::<Vec<OKXBookMsg>>(data) {
                let data_vec = parse_book10_msg_vec(
                    book_msgs,
                    instrument_id,
                    price_precision,
                    size_precision,
                    ts_init,
                )?;
                Ok(Some(NautilusWsMessage::Data(data_vec)))
            } else {
                anyhow::bail!("Failed to deserialize Books channel data as Vec<OKXBookMsg>")
            }
        }
        _ => {
            log::warn!("Unsupported channel for message parsing: {channel:?}");
            Ok(None)
        }
    }
}

#[cfg(test)]
mod tests {
    use ahash::AHashMap;
    use nautilus_core::nanos::UnixNanos;
    use nautilus_model::{
        data::bar::BAR_SPEC_1_DAY_LAST,
        enums::GreeksConvention,
        identifiers::{ClientOrderId, Symbol},
        instruments::CryptoPerpetual,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the raw payload and confirm it is an array of book messages matching OKX's Books channel docs
  2. Update OKXBookMsg serde definitions in parse.rs to match the current OKX schema
  3. Ensure the channel-to-parser mapping sends books-channel data to parse_ws_message_data with the right OKXWsChannel variant
  4. Upgrade the adapter to a release with corrected OKX book parsing

Example fix

// before
anyhow::bail!("Failed to deserialize Books channel data as Vec<OKXBookMsg>")
// after
anyhow::bail!("Failed to deserialize Books channel data as Vec<OKXBookMsg>: {data:?}") // and align OKXBookMsg fields with OKX docs
Defensive patterns

Strategy: validation

Validate before calling

fn is_book_payload(msg: &serde_json::Value) -> bool {
    msg.get("data")
        .and_then(|d| d.as_array())
        .map(|a| a.iter().all(|o| o.get("action").is_some() || o.get("data").is_some()))
        .unwrap_or(false)
}

Try / catch

let data: Vec<OKXBookMsg> = match serde_json::from_value(payload) {
    Ok(d) => d,
    Err(e) => { log::warn!("book parse failed: {e}"); return; }
};

Prevention

When it happens

Trigger: A Books/BBO channel WS message arrives where `data` is not an array of OKXBookMsg-compatible objects (missing fields like action/data types, non-array payload, or schema drift from OKX).

Common situations: OKX changes the books snapshot/update format; a depth channel message is misrouted to the Books parser; mocked or recorded payloads used in tests are incomplete.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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