{"record":{"id":"d8f9f272fd8e54ad","repo":"nautechsystems/nautilus_trader","slug":"failed-e-d8f9f2","errorCode":null,"errorMessage":"{FAILED}: {e}","messagePattern":"\\{FAILED\\}: \\{e\\}","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/identifiers/instrument_id.rs","lineNumber":209,"sourceCode":"                })?\n            }\n\n            #[cfg(not(feature = \"defi\"))]\n            Symbol::new_checked(symbol_part).map_err(|source| InstrumentIdError::InvalidSymbol {\n                value: s.to_string(),\n                source: Box::new(source),\n            })?\n        };\n\n        Ok(Self { symbol, venue })\n    }\n}\n\nimpl<T: AsRef<str>> From<T> for InstrumentId {\n    fn from(value: T) -> Self {\n        match Self::from_str(value.as_ref()) {\n            Ok(instrument_id) => instrument_id,\n            Err(e) => panic!(\"{FAILED}: {e}\"),\n        }\n    }\n}\n\nimpl Debug for InstrumentId {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"\\\"{}.{}\\\"\", self.symbol, self.venue)\n    }\n}\n\nimpl Display for InstrumentId {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}.{}\", self.symbol, self.venue)\n    }\n}\n\nimpl Serialize for InstrumentId {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/identifiers/instrument_id.rs#L191-L227","documentation":"The blanket `From<T: AsRef<str>> for InstrumentId` conversion panics when the string cannot be parsed as a valid `InstrumentId` (it must contain a symbol and venue separated by '.', e.g. \"AAPL.NASDAQ\", with valid non-empty parts). The panic reuses the underlying parse error message, prefixed by the FAILED constant. It exists so ergonomic `value.into()` conversions fail loudly instead of producing invalid IDs.","triggerScenarios":"Calling `InstrumentId::from(\"BTCUSD\")` (no venue), `InstrumentId::from(\".NSE\")` (empty symbol), `InstrumentId::from(\"AAPL.nasdaq.\")` (malformed venue), or `.into()` on any user-provided string with wrong format.","commonSituations":"Reading instrument symbols from CSV/config files where venue suffix is missing; user config like 'instrument=BTCUSDT' without exchange; joining symbol+venue with the wrong separator (':' or '-'); empty cells in data files.","solutions":["Ensure the string has the '<SYMBOL>.<VENUE>' format with non-empty symbol and venue before converting.","Use `InstrumentId::from_str(...)` / `InstrumentId::checked_from_str` and handle the Err explicitly instead of the panicking `From` impl.","Validate the venue against `Venue::from_str` and the symbol against `Symbol` first.","Fix upstream data/config sources to always include the venue suffix."],"exampleFix":"// before\nlet id: InstrumentId = \"BTCUSDT\".into(); // panics: no venue\n// after\nlet id = InstrumentId::from_str(\"BTCUSDT.BINANCE\").expect(\"valid instrument id\");","handlingStrategy":"validation","validationCode":"fn parse_instrument_id(s: &str) -> Result<InstrumentId, String> {\n    match s.rsplit_once('.') {\n        Some((sym, venue)) if !sym.is_empty() && !venue.is_empty() => {\n            InstrumentId::from_str(s).map_err(|e| e.to_string())\n        }\n        _ => Err(format!(\"expected '<SYMBOL>.<VENUE>', got '{s}'\")),\n    }\n}","typeGuard":"fn is_instrument_id_shape(s: &str) -> bool {\n    matches!(s.rsplit_once('.'), Some((sym, venue)) if !sym.is_empty() && !venue.is_empty())\n}","tryCatchPattern":"// Prefer checked parsing over the panicking From impl\nlet id = match InstrumentId::from_str(raw) {\n    Ok(id) => id,\n    Err(e) => { log::error!(\"bad instrument id '{raw}': {e}\"); return Err(e.into()); }\n};","preventionTips":["Always store instrument ids in SYMBOL.VENUE form in configs and data files","Use InstrumentId::from_str/checked_from_str at boundaries and reserve From for internal trusted strings","Validate venues against known venues at startup","Reject empty CSV/config cells before conversion"],"tags":["rust","parsing","panic","instrument-id"],"backgroundTag":"invalid-identifier-format","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"}