{"record":{"id":"409898f0f971dbbc","repo":"nautechsystems/nautilus_trader","slug":"invalid-spread-symbol-format-for-component-compo","errorCode":null,"errorMessage":"Invalid spread symbol format for component: {component}","messagePattern":"Invalid spread symbol format for component: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/interactive_brokers/src/common/parse.rs","lineNumber":1253,"sourceCode":"            }\n        }\n\n        // Check for positive ratio: (ratio)symbol\n        if let Some(rest) = component.strip_prefix('(')\n            && let Some(pos) = rest.find(')')\n        {\n            let ratio_str = &rest[..pos];\n            let symbol_value = &rest[pos + 1..];\n\n            if let Ok(ratio) = ratio_str.parse::<i32>() {\n                let leg_instrument_id =\n                    InstrumentId::new(NautilusSymbol::from(symbol_value), venue);\n                result.push((leg_instrument_id, ratio));\n                continue;\n            }\n        }\n\n        anyhow::bail!(\"Invalid spread symbol format for component: {component}\");\n    }\n\n    // Sort result alphabetically by symbol\n    result.sort_by(|a, b| a.0.symbol.as_str().cmp(b.0.symbol.as_str()));\n\n    Ok(result)\n}\n\n#[cfg(test)]\nmod tests {\n    use ibapi::contracts::{Contract, Currency, Exchange, OptionRight, SecurityType, Symbol};\n    use nautilus_model::identifiers::InstrumentId;\n    use rstest::rstest;\n\n    use super::{\n        exchange_to_mic_venue, ib_contract_to_instrument_id_simplified,\n        instrument_id_to_ib_contract, possible_exchanges_for_venue,\n    };","sourceCodeStart":1235,"sourceCodeEnd":1271,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/interactive_brokers/src/common/parse.rs#L1235-L1271","documentation":"parse_spread_instrument_id_to_legs decodes a spread instrument ID symbol whose components are encoded leg strings like 'SYMBOL:RATIO'; a component that matches neither the expected leg pattern nor a recognized special case produces this error.","triggerScenarios":"Calling parse_spread_instrument_id_to_legs (directly or via fetch_spread_instrument) with a manually constructed or malformed spread symbol, e.g. missing the ':ratio' part, non-numeric ratio, or extra separators.","commonSituations":"Hand-writing spread symbols instead of using create_spread_instrument_id; symbols mutated/truncated by other tooling; legacy spread symbol formats no longer recognized.","solutions":["Construct spread instrument IDs with create_spread_instrument_id instead of manual strings","Check the failing component has the expected 'SYMBOL:RATIO' encoding with an integer ratio","Log/print the full spread symbol and compare each component against the parser's expected format","If a legacy format is involved, regenerate the spread ID in the current format"],"exampleFix":"// before\nlet id = InstrumentId::from(\"AAPL251212C00250000-MSFT.OPT\"); // no :ratio\n// after\nlet id = create_spread_instrument_id(&[\n    (InstrumentId::from(\"AAPL  251212C00250000.OPRA\"), -1),\n    (InstrumentId::from(\"AAPL  251212P00250000.OPRA\"), 1),\n])?;","handlingStrategy":"try-catch","validationCode":"fn looks_like_leg(c: &str) -> bool {\n    let mut parts = c.rsplitn(2, ':');\n    match (parts.next(), parts.next()) {\n        (Some(ratio), Some(_)) => ratio.parse::<i32>().is_ok(),\n        _ => false,\n    }\n}","typeGuard":null,"tryCatchPattern":"match parse_spread_instrument_id_to_legs(&spread_id) {\n    Ok(legs) => legs,\n    Err(e) if e.to_string().starts_with(\"Invalid spread symbol format\") => {\n        tracing::error!(\"malformed spread symbol {}: {e}\", spread_id.symbol);\n        Vec::new()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Generate spread symbols only via create_spread_instrument_id","Keep the 'SYMBOL:RATIO' encoding intact; avoid transforming symbols elsewhere","Add round-trip tests: create -> parse should always succeed"],"tags":["rust","symbol-parsing","options-spreads","interactive-brokers"],"backgroundTag":"invalid-argument-format","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"}