{"record":{"id":"ffcd33c22bf96ba4","repo":"nautechsystems/nautilus_trader","slug":"cannot-expand-parent-subscription-for-instrument","errorCode":null,"errorMessage":"Cannot expand parent subscription for {instrument_id}: symbol does not parse as `<root>.<class>` with a recognized class suffix","messagePattern":"Cannot expand parent subscription for (.+?): symbol does not parse as `<root>\\.<class>` with a recognized class suffix","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/mod.rs","lineNumber":5625,"sourceCode":"    }\n}\n\n// Resolves parent expansion components for a book subscription command.\n//\n// Returns Ok(Some((root, class))) when params carries PARAMS_IS_PARENT=true and\n// the instrument_id parses as a recognized <root>.<class> shape; Ok(None) for\n// concrete (non-parent) subscriptions; Err when the caller asserts a parent\n// subscription but the id cannot be parsed, so subscribe entries can reject up\n// front before touching state.\nfn resolve_parent_components(\n    instrument_id: &InstrumentId,\n    params: Option<&Params>,\n) -> anyhow::Result<Option<(Ustr, InstrumentClass)>> {\n    if !is_parent_subscription(params) {\n        return Ok(None);\n    }\n    let Some((root, class)) = instrument_id.parse_parent_components() else {\n        anyhow::bail!(\n            \"Cannot expand parent subscription for {instrument_id}: \\\n             symbol does not parse as `<root>.<class>` with a recognized class suffix\"\n        );\n    };\n    Ok(Some((Ustr::from(root), class)))\n}\n\nfn register_external_streaming_type(cmd: &SubscribeCommand) {\n    if let Some(payload_type) = streaming_payload_type(cmd) {\n        msgbus::get_message_bus()\n            .borrow_mut()\n            .add_streaming_type(payload_type);\n    }\n}\n\nfn publish_external_data_command<T>(client_id: ClientId, command: &T)\nwhere\n    T: Any,","sourceCodeStart":5607,"sourceCodeEnd":5643,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/mod.rs#L5607-L5643","documentation":"Parent subscriptions (subscribing to all contracts of a root, e.g. 'ES.NYMEX' as a parent) are expressed as symbol strings of the form '<root>.<class>' where class is a recognized InstrumentClass suffix. When expanding such a subscription, the engine could not split the instrument ID into root and class components, meaning the symbol is malformed or uses an unrecognized suffix.","triggerScenarios":"Passing params that mark a subscription as a parent subscription (is_parent_subscription) together with an instrument_id whose symbol does not match '<root>.<class>' — missing the dot, or using an unknown class suffix (not FUTURE, OPTION, etc.).","commonSituations":"Typos in the parent symbol ('ESX' instead of 'ES.FUTURE'); inventing custom class suffixes the parser doesn't recognize; using a full contract ID like 'ESH6.XCME' where a parent root is expected.","solutions":["Use the correct parent format '<root>.<class>', e.g. 'ES.FUTURE' (with a recognized InstrumentClass suffix).","Check parse_parent_components / InstrumentClass for the list of recognized suffixes and match one exactly.","If you want a specific contract, don't set the parent-subscription params; subscribe to the full instrument ID directly."],"exampleFix":"// before\nengine.subscribe(InstrumentId::from(\"ESX\"), Some(parent_params))?;\n// after\nengine.subscribe(InstrumentId::from(\"ES.FUTURE\"), Some(parent_params))?;","handlingStrategy":"validation","validationCode":"if is_parent_subscription(params) && instrument_id.parse_parent_components().is_none() {\n    anyhow::bail!(\"{} is not a valid parent symbol <root>.<class>\", instrument_id);\n}","typeGuard":"fn is_valid_parent_symbol(id: &InstrumentId) -> bool {\n    id.parse_parent_components().is_some()\n}","tryCatchPattern":"match expand_parent_subscription(&instrument_id, params) {\n    Err(e) if e.to_string().contains(\"does not parse as `<root>.<class>`\") => {\n        eprintln!(\"use e.g. ES.FUTURE for parent subscriptions\");\n    }\n    r => r?,\n}","preventionTips":["Always write parent symbols as <root>.<class>, e.g. ES.FUTURE","Check the recognized InstrumentClass suffixes before inventing symbols","Don't set parent-subscription params for full contract instrument IDs"],"tags":["rust","data-engine","instrument-id","parsing"],"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-14T05:17:10.506Z"}