{"record":{"id":"ff283e42929d3f2e","repo":"nautechsystems/nautilus_trader","slug":"missing-root-symbol-for","errorCode":null,"errorMessage":"Missing root_symbol for {}","messagePattern":"Missing root_symbol for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bitmex/src/websocket/messages.rs","lineNumber":582,"sourceCode":"    pub indicative_tax_rate: Option<f64>,\n    pub open_interest: Option<i64>,\n    pub open_value: Option<i64>,\n    pub fair_basis: Option<f64>,\n    pub fair_basis_rate: Option<f64>,\n    pub fair_price: Option<f64>,\n    pub timestamp: Timestamp,\n}\n\nimpl TryFrom<BitmexInstrumentMsg> for crate::http::models::BitmexInstrument {\n    type Error = anyhow::Error;\n\n    fn try_from(msg: BitmexInstrumentMsg) -> Result<Self, Self::Error> {\n        use crate::common::enums::{BitmexInstrumentState, BitmexInstrumentType};\n\n        // Required fields\n        let root_symbol = msg\n            .root_symbol\n            .ok_or_else(|| anyhow::anyhow!(\"Missing root_symbol for {}\", msg.symbol))?;\n        let underlying = msg\n            .underlying\n            .ok_or_else(|| anyhow::anyhow!(\"Missing underlying for {}\", msg.symbol))?;\n        let quote_currency = msg\n            .quote_currency\n            .ok_or_else(|| anyhow::anyhow!(\"Missing quote_currency for {}\", msg.symbol))?;\n        let tick_size = msg\n            .tick_size\n            .ok_or_else(|| anyhow::anyhow!(\"Missing tick_size for {}\", msg.symbol))?;\n        let multiplier = msg\n            .multiplier\n            .ok_or_else(|| anyhow::anyhow!(\"Missing multiplier for {}\", msg.symbol))?;\n        let is_quanto = msg\n            .is_quanto\n            .ok_or_else(|| anyhow::anyhow!(\"Missing is_quanto for {}\", msg.symbol))?;\n        let is_inverse = msg\n            .is_inverse\n            .ok_or_else(|| anyhow::anyhow!(\"Missing is_inverse for {}\", msg.symbol))?;","sourceCodeStart":564,"sourceCodeEnd":600,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bitmex/src/websocket/messages.rs#L564-L600","documentation":"The TryFrom<BitmexInstrumentMsg> conversion for instrument definitions requires `root_symbol`, but the WebSocket instrument message omitted it (null). The conversion fails so an incomplete instrument definition is never used downstream.","triggerScenarios":"Receiving an `instrument` WS message for a symbol whose root_symbol is null — e.g. composite/index symbols, delisted instruments, or BitMEX emitting partial instrument snapshots.","commonSituations":"Subscribing to the full instrument table where some rows (indices, .XBT symbols) lack root_symbol; BitMEX partial updates carrying only changed fields.","solutions":["Skip/catch the failed conversion for that symbol and continue processing other instruments.","Restrict the instrument subscription to symbols with complete definitions.","Merge partial WS updates into a cached full instrument snapshot instead of converting each update standalone.","Check whether the symbol is an index/composite that legitimately lacks root_symbol and handle it separately."],"exampleFix":"// before\nlet instrument = BitmexInstrumentMsg::try_from(msg)?;\n// after\nmatch BitmexInstrumentMsg::try_from(msg) {\n    Ok(i) => handle(i),\n    Err(e) => log::debug!(\"Skipping incomplete instrument msg: {e}\"),\n}","handlingStrategy":"fallback","validationCode":"if msg.root_symbol.is_none() { /* skip or fetch full snapshot via REST */ }","typeGuard":"fn complete_instrument(msg: &BitmexInstrumentMsg) -> bool {\n    msg.root_symbol.is_some() && msg.underlying.is_some() && msg.quote_currency.is_some()\n}","tryCatchPattern":"match TryInto::<InstrumentDef>::try_into(msg) {\n    Ok(def) => apply(def),\n    Err(e) => log::debug!(\"partial instrument update ignored: {e}\"),\n}","preventionTips":["Bootstrap instruments from a full REST snapshot before consuming WS deltas.","Expect index/composite symbols to lack derivative-only fields.","Skip (do not fail) individual instrument conversions inside bulk subscriptions."],"tags":["websocket","bitmex","instrument","missing-field"],"backgroundTag":"missing-required-config-field","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"}