{"record":{"id":"154d34634caefcf5","repo":"nautechsystems/nautilus_trader","slug":"empty-bids-array-for-instrument-id","errorCode":null,"errorMessage":"Empty bids array for {instrument_id}","messagePattern":"Empty bids array for (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/adapters/okx/src/websocket/parse.rs","lineNumber":1039,"sourceCode":"    OrderBookDeltas::new_checked(instrument_id, deltas)\n}\n\n/// Parses an OKX book message into a Nautilus quote tick.\n///\n/// # Errors\n///\n/// Returns an error if any quote levels contain values that cannot be parsed.\npub fn parse_quote_msg(\n    msg: &OKXBookMsg,\n    instrument_id: InstrumentId,\n    price_precision: u8,\n    size_precision: u8,\n    ts_init: UnixNanos,\n) -> anyhow::Result<QuoteTick> {\n    let best_bid: &OrderBookEntry = msg\n        .bids\n        .first()\n        .ok_or_else(|| anyhow::anyhow!(\"Empty bids array for {instrument_id}\"))?;\n    let best_ask: &OrderBookEntry = msg\n        .asks\n        .first()\n        .ok_or_else(|| anyhow::anyhow!(\"Empty asks array for {instrument_id}\"))?;\n\n    let bid_price = parse_price(&best_bid.price, price_precision)?;\n    let ask_price = parse_price(&best_ask.price, price_precision)?;\n    let bid_size = parse_quantity(&best_bid.size, size_precision)?;\n    let ask_size = parse_quantity(&best_ask.size, size_precision)?;\n    let ts_event = parse_millisecond_timestamp(msg.ts);\n\n    QuoteTick::new_checked(\n        instrument_id,\n        bid_price,\n        ask_price,\n        bid_size,\n        ask_size,\n        ts_event,","sourceCodeStart":1021,"sourceCodeEnd":1057,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/websocket/parse.rs#L1021-L1057","documentation":"When parsing an OKX quote (ticker) message into a QuoteTick, the adapter takes the first element of the bids (and asks) arrays as the best price. OKX occasionally emits quote updates with empty bid or ask sides (one-sided market or snapshot gap); since a QuoteTick requires both, the parser returns this error instead of producing a tick.","triggerScenarios":"A quote message arrives whose `bids` array is empty (no best bid available) while parsing via parse_quote_msg; similarly for empty asks (see the sibling error).","commonSituations":"Illiquid or newly listed instruments with no resting bids; market open/auction phases; OKX sending one-sided book snapshots during volatile periods.","solutions":["Skip/ignore the message: treat one-sided quotes as no-data rather than errors at the call site.","Subscribe to the depth/book channel as a fallback source for best bid/ask on illiquid instruments.","Filter out instruments with persistently one-sided books if your strategy cannot handle missing quotes."],"exampleFix":"// before\nlet quote = parse_quote_msg(msg, ...)?; // errors on empty bids\n// after\nmatch parse_quote_msg(msg, ...) {\n    Ok(q) => handle(q),\n    Err(e) if e.to_string().contains(\"Empty bids\") => continue, // skip one-sided quote\n    Err(e) => return Err(e),\n}","handlingStrategy":"fallback","validationCode":"// rust\n// pre-check if you control message handling\nif msg.bids.is_empty() || msg.asks.is_empty() { skip_quote(); }","typeGuard":"// rust\nfn has_two_sided_book(bids: &[OrderBookEntry], asks: &[OrderBookEntry]) -> bool {\n    !bids.is_empty() && !asks.is_empty()\n}","tryCatchPattern":"// rust\nmatch parse_quote_msg(msg, ...) {\n    Ok(q) => handle(q),\n    Err(e) if e.to_string().starts_with(\"Empty bids\") || e.to_string().starts_with(\"Empty asks\") => skip_quote(),\n    Err(e) => return Err(e),\n}","preventionTips":["Expect one-sided quotes on illiquid/newly listed instruments and skip them gracefully.","Use depth/book data as a fallback for best bid/ask when quotes are one-sided.","Do not treat empty-side quotes as fatal; they are normal during volatile or auction phases."],"tags":["okx","market-data","quotes","parsing"],"backgroundTag":"empty-result-set","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}