nautechsystems/nautilus_trader · error
Cannot expand parent subscription for {instrument_id}: symbo
Error message
Cannot expand parent subscription for {instrument_id}: symbol does not parse as `<root>.<class>` with a recognized class suffix What it means
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.
Source
Thrown at crates/data/src/engine/mod.rs:5625
}
}
// Resolves parent expansion components for a book subscription command.
//
// Returns Ok(Some((root, class))) when params carries PARAMS_IS_PARENT=true and
// the instrument_id parses as a recognized <root>.<class> shape; Ok(None) for
// concrete (non-parent) subscriptions; Err when the caller asserts a parent
// subscription but the id cannot be parsed, so subscribe entries can reject up
// front before touching state.
fn resolve_parent_components(
instrument_id: &InstrumentId,
params: Option<&Params>,
) -> anyhow::Result<Option<(Ustr, InstrumentClass)>> {
if !is_parent_subscription(params) {
return Ok(None);
}
let Some((root, class)) = instrument_id.parse_parent_components() else {
anyhow::bail!(
"Cannot expand parent subscription for {instrument_id}: \
symbol does not parse as `<root>.<class>` with a recognized class suffix"
);
};
Ok(Some((Ustr::from(root), class)))
}
fn register_external_streaming_type(cmd: &SubscribeCommand) {
if let Some(payload_type) = streaming_payload_type(cmd) {
msgbus::get_message_bus()
.borrow_mut()
.add_streaming_type(payload_type);
}
}
fn publish_external_data_command<T>(client_id: ClientId, command: &T)
where
T: Any,View on GitHub (pinned to 18893faf8b)
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.
Example fix
// before
engine.subscribe(InstrumentId::from("ESX"), Some(parent_params))?;
// after
engine.subscribe(InstrumentId::from("ES.FUTURE"), Some(parent_params))?; Defensive patterns
Strategy: validation
Validate before calling
if is_parent_subscription(params) && instrument_id.parse_parent_components().is_none() {
anyhow::bail!("{} is not a valid parent symbol <root>.<class>", instrument_id);
} Type guard
fn is_valid_parent_symbol(id: &InstrumentId) -> bool {
id.parse_parent_components().is_some()
} Try / catch
match expand_parent_subscription(&instrument_id, params) {
Err(e) if e.to_string().contains("does not parse as `<root>.<class>`") => {
eprintln!("use e.g. ES.FUTURE for parent subscriptions");
}
r => r?,
} Prevention
- 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
When it happens
Trigger: 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.).
Common situations: 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.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- {FAILED}: {e}
- cannot derive currency from {instrument_id}
- Invalid `InstrumentId` for 'instrument_id'
- Invalid `external_order_claims` instrument ID {claim}: {e}
- Invalid scientific notation exponent '{exponent}': must be a
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ffcd33c22bf96ba4.
Report an issue: GitHub.