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
- Inspect the raw payload and confirm it is an array of book messages matching OKX's Books channel docs
- Update OKXBookMsg serde definitions in parse.rs to match the current OKX schema
- Ensure the channel-to-parser mapping sends books-channel data to parse_ws_message_data with the right OKXWsChannel variant
- 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
- Confirm channel routing maps books messages to the Books parser
- Track OKX changelog for depth format updates
- Validate recorded test payloads against OKXBookMsg
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
- Failed to deserialize instrument payload
- Bybit order book update missing bid levels and no previous q
- Bybit order book update missing ask levels and no previous q
- Invalid `BarSpecification` for channel, was {bar_spec}
- errors.join("; ")
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1cb7c0a651d967d6.
Report an issue: GitHub.