{"record":{"id":"7a2bb120b7a2fdc0","repo":"nautechsystems/nautilus_trader","slug":"cannot-resolve-bag-contract-without-combo-legs-or","errorCode":null,"errorMessage":"Cannot resolve BAG contract without combo legs or cached contract ID","messagePattern":"Cannot resolve BAG contract without combo legs or cached contract ID","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/interactive_brokers/src/providers/instruments.rs","lineNumber":515,"sourceCode":"            return self.resolve_spread_instrument_id_for_contract(contract);\n        }\n\n        let venue = self.determine_venue(contract, None);\n\n        match self.config.symbology_method {\n            SymbologyMethod::Simplified => {\n                ib_contract_to_instrument_id_simplified(contract, Some(venue))\n            }\n            SymbologyMethod::Raw => ib_contract_to_instrument_id_raw(contract, Some(venue)),\n        }\n    }\n\n    fn resolve_spread_instrument_id_for_contract(\n        &self,\n        contract: &Contract,\n    ) -> anyhow::Result<InstrumentId> {\n        if contract.combo_legs.is_empty() {\n            anyhow::bail!(\"Cannot resolve BAG contract without combo legs or cached contract ID\");\n        }\n\n        let mut leg_tuples = Vec::with_capacity(contract.combo_legs.len());\n\n        for combo_leg in &contract.combo_legs {\n            let leg_instrument_id = self\n                .get_instrument_id_by_contract_id(combo_leg.contract_id)\n                .with_context(|| {\n                    format!(\n                        \"Cannot resolve BAG leg con_id {} to cached instrument ID\",\n                        combo_leg.contract_id\n                    )\n                })?;\n            let ratio = IbAction::from_str(combo_leg.action.as_str())\n                .context(\"Invalid BAG combo leg action\")?\n                .signed_multiplier()\n                * combo_leg.ratio;\n","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/interactive_brokers/src/providers/instruments.rs#L497-L533","documentation":"BAG (spread/combo) contracts in IB carry their definition in combo_legs. This error fires when the adapter is asked to resolve a BAG contract's instrument ID but the contract has no combo legs and no cached contract ID, so there is no leg data from which to derive the spread instrument ID.","triggerScenarios":"resolve_spread_instrument_id_for_contract receives a Contract with security_type BAG whose combo_legs list is empty and for which no prior contract-details response cached an identifier.","commonSituations":"Constructing a BAG contract by hand and forgetting to populate combo_legs, or receiving a bare BAG contract from a subscription callback before full contract details arrived.","solutions":["Populate contract.combo_legs with the spread's legs (each with con_id, ratio, and action) before resolution.","Fetch full contract details for the BAG con_id first so the cached ID/legs are available.","For non-BAG contracts, don't route through the spread-resolution path.","Verify the security type is actually BAG; a mislabeled contract may bypass leg construction."],"exampleFix":"// before: empty BAG contract\nlet contract = Contract { security_type: SecurityType::Bag, ..Default::default() };\n// after: BAG contract with legs\nlet contract = Contract {\n    security_type: SecurityType::Bag,\n    combo_legs: vec![\n        ComboLeg { con_id: 552824014, ratio: 1, action: \"BUY\".into(), ..Default::default() },\n        ComboLeg { con_id: 552824046, ratio: 1, action: \"SELL\".into(), ..Default::default() },\n    ],\n    ..Default::default()\n};","handlingStrategy":"validation","validationCode":"fn can_resolve_bag(contract: &Contract) -> bool {\n    contract.security_type != SecurityType::Bag\n        || !contract.combo_legs.is_empty()\n        || contract.con_id != 0 // cached contract ID available\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct BAG contracts without combo_legs","Fetch full contract details before spread resolution","Route single-instrument contracts to the non-spread path"],"tags":["interactive-brokers","bag-contract","spread","instrument-resolution"],"backgroundTag":"missing-required-argument","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"}