{"record":{"id":"4b50d09dcb616045","repo":"nautechsystems/nautilus_trader","slug":"invalid-external-order-instrument-ids-type-e","errorCode":null,"errorMessage":"Invalid `external_order_instrument_ids` type: {e}","messagePattern":"Invalid `external_order_instrument_ids` type: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/python/node.rs","lineNumber":1911,"sourceCode":"\nfn extract_external_order_instrument_ids_config_attr(\n    config_obj: &Bound<'_, PyAny>,\n) -> anyhow::Result<Option<Vec<InstrumentId>>> {\n    let Ok(claims) = config_obj.getattr(\"external_order_instrument_ids\") else {\n        return Ok(None);\n    };\n\n    if claims.is_none() {\n        return Ok(None);\n    }\n\n    if let Ok(claims) = claims.extract::<Vec<InstrumentId>>() {\n        return Ok(Some(claims));\n    }\n\n    let claim_strings = claims\n        .extract::<Vec<String>>()\n        .map_err(|e| anyhow::anyhow!(\"Invalid `external_order_instrument_ids` type: {e}\"))?;\n    let claims = claim_strings\n        .into_iter()\n        .map(|claim| {\n            InstrumentId::from_str(&claim).map_err(|e| {\n                anyhow::anyhow!(\n                    \"Invalid `external_order_instrument_ids` instrument ID {claim}: {e}\"\n                )\n            })\n        })\n        .collect::<anyhow::Result<Vec<_>>>()?;\n\n    Ok(Some(claims))\n}\n\n#[cfg(feature = \"examples\")]\ntype BuiltinActorRegister = for<'py> fn(&mut LiveNode, &Bound<'py, PyAny>) -> PyResult<()>;\n\n#[cfg(feature = \"examples\")]","sourceCodeStart":1893,"sourceCodeEnd":1929,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/python/node.rs#L1893-L1929","documentation":"Raised while extracting the external_order_instrument_ids attribute from a strategy config: the value is neither a list of InstrumentId objects nor a list of strings parseable as InstrumentId. The node accepts both forms and rejects anything else.","triggerScenarios":"Setting external_order_instrument_ids in the strategy config to a wrong shape: a single string instead of a list, a list of non-instrument strings (typos like 'AAPL' without venue, or 'EUR/USD' when venue format is required), a set, tuple, or None-adjacent non-list type.","commonSituations":"Hand-editing YAML/JSON configs with a comma-joined string; missing the venue suffix (\"AAPL\" instead of \"AAPL.NASDAQ\"); passing a tuple from Python code where a list is expected by the extractor.","solutions":["Ensure the value is a list, e.g. [\"AAPL.NASDAQ\", \"MSFT.NASDAQ\"]","Use fully qualified instrument IDs with venue (InstrumentId::from_str parses venue.symbol); fix IDs flagged by the follow-up 'instrument ID' error","In Python configs pass list(instrument_ids), not a tuple or single string","Validate IDs up front with InstrumentId.from_str in a sanity check before launching the node"],"exampleFix":"// before\nconfig[\"external_order_instrument_ids\"] = \"AAPL.NASDAQ,MSFT.NASDAQ\"\n// after\nconfig[\"external_order_instrument_ids\"] = [\"AAPL.NASDAQ\", \"MSFT.NASDAQ\"]","handlingStrategy":"validation","validationCode":"from nautilus_trader.model.identifiers import InstrumentId\nids = config[\"external_order_instrument_ids\"]\nassert isinstance(ids, list), \"must be a list\"\nparsed = [InstrumentId.from_str(i) for i in ids]  # raises on bad IDs","typeGuard":"def valid_external_ids(value) -> bool:\n    from nautilus_trader.model.identifiers import InstrumentId\n    if not isinstance(value, list):\n        return False\n    try:\n        [InstrumentId.from_str(i) for i in value]\n        return True\n    except Exception:\n        return False","tryCatchPattern":"try:\n    node.add_strategy_from_config(cfg)\nexcept Exception as e:\n    if \"external_order_instrument_ids\" in str(e):\n        raise ValueError(\"external_order_instrument_ids must be a list of 'SYMBOL.VENUE' strings\") from e\n    raise","preventionTips":["Always pass a list of fully qualified 'SYMBOL.VENUE' strings","Never pass a single comma-joined string or a tuple","Validate IDs with InstrumentId.from_str before configuring the node"],"tags":["config","instrument-id","type-mismatch","live-trading"],"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"}