{"record":{"id":"7d9cf8f2cd03b48f","repo":"nautechsystems/nautilus_trader","slug":"missing-quote-currency-for","errorCode":null,"errorMessage":"Missing quote_currency for {}","messagePattern":"Missing quote_currency for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bitmex/src/websocket/messages.rs","lineNumber":588,"sourceCode":"    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))?;\n\n        // Parse state - default to Open if not present\n        let state = msg\n            .state\n            .and_then(|s| serde_json::from_str::<BitmexInstrumentState>(&format!(\"\\\"{s}\\\"\")).ok())\n            .unwrap_or(BitmexInstrumentState::Open);","sourceCodeStart":570,"sourceCodeEnd":606,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bitmex/src/websocket/messages.rs#L570-L606","documentation":"The instrument message conversion requires `quote_currency`, which arrived null in the BitmexInstrumentMsg. Without a quote currency no instrument can be defined, so the conversion aborts with this error naming the symbol.","triggerScenarios":"WS instrument message for a symbol with quote_currency: null — index symbols (e.g. .BVOL), partial snapshots, or malformed/delisted instrument rows.","commonSituations":"Subscribing to all instruments (indices and special symbols included); BitMEX schema changes; cached definitions not merged with partial delta updates.","solutions":["Skip the affected symbol; convert only messages with all required fields present.","Maintain a snapshot cache so partial deltas never drive a full conversion.","Exclude index/special symbols from instrument subscriptions.","Verify BitMEX instrument schema and update adapter mappings if changed."],"exampleFix":"// before\nlet def = BitmexInstrumentDef::try_from(msg).context(\"convert instrument\")?;\n// after\nlet Ok(def) = BitmexInstrumentDef::try_from(msg) else {\n    log::debug!(\"Skipping instrument msg missing required fields\");\n    return Ok(());\n};","handlingStrategy":"fallback","validationCode":"if msg.quote_currency.is_none() { /* skip symbol */ }","typeGuard":"fn convertible(msg: &BitmexInstrumentMsg) -> bool {\n    msg.root_symbol.is_some() && msg.underlying.is_some() && msg.quote_currency.is_some()\n}","tryCatchPattern":"if let Err(e) = convert_instrument(&msg) {\n    debug!(\"instrument {} skipped: {e}\", msg.symbol);\n}","preventionTips":["Exclude index/special symbols (e.g. .BVOL) from instrument subscriptions.","Refetch a complete definition via REST when a WS row is incomplete.","Treat each WS instrument row independently so one failure does not abort the batch."],"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-14T05:17:10.506Z"}