nautechsystems/nautilus_trader · error
Expected array payload: {e}
Error message
Expected array payload: {e} What it means
parse_message_vec deserializes a serde_json::Value into Vec<T> before applying the per-message parser. The error 'Expected array payload' is raised when the JSON value is not an array (or the elements don't match T), e.g. an object or error payload from OKX.
Source
Thrown at crates/adapters/okx/src/common/parse.rs:1364
/// Reduces code duplication by providing a common pattern for deserializing JSON arrays,
/// parsing each message, and wrapping results in Nautilus Data enum variants.
///
/// # Errors
///
/// Returns an error if the payload is not an array or if individual messages
/// cannot be parsed.
pub fn parse_message_vec<T, R, F, W>(
data: serde_json::Value,
parser: F,
wrapper: W,
) -> anyhow::Result<Vec<Data>>
where
T: DeserializeOwned,
F: Fn(&T) -> anyhow::Result<R>,
W: Fn(R) -> Data,
{
let messages: Vec<T> =
serde_json::from_value(data).map_err(|e| anyhow::anyhow!("Expected array payload: {e}"))?;
let mut results = Vec::with_capacity(messages.len());
for message in &messages {
let parsed = parser(message)?;
results.push(wrapper(parsed));
}
Ok(results)
}
/// Converts a Nautilus bar specification into the matching OKX candle channel.
///
/// # Errors
///
/// Returns an error if the provided bar specification does not have a matching
/// OKX websocket channel.
pub fn bar_spec_as_okx_channel(bar_spec: BarSpecification) -> anyhow::Result<OKXWsChannel> {View on GitHub (pinned to 18893faf8b)
Solutions
- Log the raw payload and confirm whether it is an OKX error/event message rather than a data array
- Handle OKX 'event' messages (subscribe/error) before dispatching to array parsers
- Check that the subscribed channel produces the expected array-of-records shape
- Verify adapter/OKX API version alignment for the channel's schema
Example fix
// before
let reports = parse_message_vec(&data, parse_ticker_msg, Data::Ticker)?;
// after
if !data.is_array() {
tracing::warn!(?data, "Non-array payload; skipping");
return Ok(Vec::new());
}
let reports = parse_message_vec(&data, parse_ticker_msg, Data::Ticker)?; Defensive patterns
Strategy: type-guard
Validate before calling
fn is_array_payload(v: &serde_json::Value) -> bool { v.is_array() }
if !is_array_payload(&data) { /* handle OKX event/error message first */ } Type guard
fn as_msg_array(v: &serde_json::Value) -> Option<&Vec<serde_json::Value>> { v.as_array() } Try / catch
match parse_message_vec(&data, parse_ticker_msg, Data::Ticker) {
Ok(data_vec) => handle(data_vec),
Err(e) => tracing::debug!("non-array websocket payload ignored: {e:#}"),
} Prevention
- Route OKX 'event' (subscribe/error) messages away from data parsers before dispatch
- Log raw payloads at debug level for schema mismatches
- Pin the channel schema with recorded-payload regression tests
When it happens
Trigger: Calling the WebSocket-specific message parsers (ticker, quote, trade, mark/index price msg vec) with a data payload that is a JSON object or string rather than an array of channel messages.
Common situations: OKX pushes an error event or subscribe confirmation instead of the data array; channel data format changes; wiring the wrong event payload into parse_message_vec.
Related errors
- Invalid `BarSpecification` for channel, was {bar_spec}
- Invalid funding_rate value: {e}
- Unsupported OKX order type: {e}
- Unsupported OKX order status: {e}
- submit order failed
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e5971f772bff0b50.
Report an issue: GitHub.