{"record":{"id":"3323cf0d4afcef8f","repo":"nautechsystems/nautilus_trader","slug":"cannot-subscribe-for-synthetic-instrument-instrum","errorCode":null,"errorMessage":"Cannot subscribe for synthetic instrument `Instrument` data","messagePattern":"Cannot subscribe for synthetic instrument `Instrument` data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/mod.rs","lineNumber":1096,"sourceCode":"                self.subscribe_option_chain(cmd);\n                return Ok(());\n            }\n            SubscribeCommand::Quotes(cmd) if cmd.instrument_id.is_synthetic() => {\n                self.subscribe_synthetic_quotes(cmd.instrument_id);\n                return Ok(());\n            }\n            SubscribeCommand::Quotes(cmd)\n                if self.is_spread_quote_command(cmd.instrument_id, cmd.params.as_ref()) =>\n            {\n                self.subscribe_spread_quotes(cmd);\n                return Ok(());\n            }\n            SubscribeCommand::Trades(cmd) if cmd.instrument_id.is_synthetic() => {\n                self.subscribe_synthetic_trades(cmd.instrument_id);\n                return Ok(());\n            }\n            SubscribeCommand::Instrument(cmd) if cmd.instrument_id.is_synthetic() => {\n                anyhow::bail!(\"Cannot subscribe for synthetic instrument `Instrument` data\");\n            }\n            SubscribeCommand::InstrumentStatus(cmd) if cmd.instrument_id.is_synthetic() => {\n                anyhow::bail!(\"Cannot subscribe for synthetic instrument `InstrumentStatus` data\");\n            }\n            SubscribeCommand::InstrumentClose(cmd) if cmd.instrument_id.is_synthetic() => {\n                anyhow::bail!(\"Cannot subscribe for synthetic instrument `InstrumentClose` data\");\n            }\n            SubscribeCommand::OptionGreeks(cmd) if cmd.instrument_id.is_synthetic() => {\n                anyhow::bail!(\"Cannot subscribe for synthetic instrument `OptionGreeks` data\");\n            }\n            _ => {} // Do nothing else\n        }\n\n        let retained = cmd.clone();\n\n        // Book ownership, including failed acquisitions, is already counted by the engine\n        let retain_on_failure = !matches!(\n            &cmd,","sourceCodeStart":1078,"sourceCodeEnd":1114,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/mod.rs#L1078-L1114","documentation":"Synthetic instrument IDs support generated Trades (and some other streams) but not `Instrument` definition subscriptions. When a SubscribeCommand for Instrument data targets a synthetic instrument ID, the engine immediately rejects it since there is no real venue to provide instrument definitions for a synthetic instrument.","triggerScenarios":"Calling subscribe (SubscribeCommand::Instrument) with an InstrumentId that is synthetic (is_synthetic() true, e.g. an ID with the synthetic venue) instead of subscribing to synthetic trades or using a real instrument ID.","commonSituations":"Code that generically subscribes to Instrument data for all instruments in a portfolio, accidentally including synthetic instruments; migrating strategies from real to synthetic instruments without changing subscription types.","solutions":["Do not subscribe to `Instrument` data for synthetic instrument IDs; instead subscribe to synthetic Trades or the stream types the engine supports for synthetics.","Filter synthetic instrument IDs out of the subscription list before issuing Instrument subscribe commands.","If instrument definitions are needed, register/define the synthetic instrument directly rather than via a data subscription."],"exampleFix":"// before\nfor id in instrument_ids {\n    engine.subscribe_instruments(id)?; // fails for synthetic ids\n}\n// after\nfor id in instrument_ids.iter().filter(|id| !id.is_synthetic()) {\n    engine.subscribe_instruments(*id)?;\n}","handlingStrategy":"type-guard","validationCode":"// Rust\nfn can_subscribe_instrument(id: InstrumentId) -> bool { !id.is_synthetic() }","typeGuard":"// Rust\nfn is_real_instrument(id: &InstrumentId) -> bool {\n    !id.is_synthetic()\n}","tryCatchPattern":"// Rust\nmatch engine.subscribe_instruments(id) {\n    Err(e) if e.to_string().contains(\"synthetic instrument `Instrument`\") => {\n        log::warn!(\"skipping Instrument subscription for synthetic {id}\");\n    }\n    r => r?,\n}","preventionTips":["Filter is_synthetic() IDs out of any generic Instrument-subscription loop.","Only subscribe to streams the engine explicitly supports for synthetics (e.g. Trades).","Keep synthetic and real instruments in separate collections."],"tags":["rust","data-engine","synthetic-instrument","subscription"],"backgroundTag":"unsupported-operation","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"}