{"record":{"id":"b7b240452f8fa32c","repo":"nautechsystems/nautilus_trader","slug":"cannot-unsubscribe-from-synthetic-instrument-inst","errorCode":null,"errorMessage":"Cannot unsubscribe from synthetic instrument `Instrument` data","messagePattern":"Cannot unsubscribe from synthetic instrument `Instrument` data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/mod.rs","lineNumber":1271,"sourceCode":"                self.unsubscribe_option_chain(cmd);\n                return Ok(());\n            }\n            UnsubscribeCommand::Quotes(cmd) if cmd.instrument_id.is_synthetic() => {\n                self.unsubscribe_synthetic_quotes(cmd.instrument_id);\n                return Ok(());\n            }\n            UnsubscribeCommand::Quotes(cmd)\n                if self.is_spread_quote_command(cmd.instrument_id, cmd.params.as_ref()) =>\n            {\n                self.unsubscribe_spread_quotes(cmd);\n                return Ok(());\n            }\n            UnsubscribeCommand::Trades(cmd) if cmd.instrument_id.is_synthetic() => {\n                self.unsubscribe_synthetic_trades(cmd.instrument_id);\n                return Ok(());\n            }\n            UnsubscribeCommand::Instrument(cmd) if cmd.instrument_id.is_synthetic() => {\n                anyhow::bail!(\"Cannot unsubscribe from synthetic instrument `Instrument` data\");\n            }\n            UnsubscribeCommand::InstrumentStatus(cmd) if cmd.instrument_id.is_synthetic() => {\n                anyhow::bail!(\n                    \"Cannot unsubscribe from synthetic instrument `InstrumentStatus` data\"\n                );\n            }\n            UnsubscribeCommand::InstrumentClose(cmd) if cmd.instrument_id.is_synthetic() => {\n                anyhow::bail!(\n                    \"Cannot unsubscribe from synthetic instrument `InstrumentClose` data\"\n                );\n            }\n            UnsubscribeCommand::OptionGreeks(cmd) if cmd.instrument_id.is_synthetic() => {\n                anyhow::bail!(\"Cannot unsubscribe from synthetic instrument `OptionGreeks` data\");\n            }\n            _ => {}\n        }\n\n        if let Some(client) = self.get_command_client(cmd.client_id(), cmd.venue()) {","sourceCodeStart":1253,"sourceCodeEnd":1289,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/mod.rs#L1253-L1289","documentation":"Unsubscribing from `Instrument` data is only valid for real instruments; for a synthetic instrument ID the engine never had a client subscription to remove, so UnsubscribeCommand::Instrument targeting a synthetic ID bails with this error. (Synthetic Trades unsubscribes are handled separately and succeed.)","triggerScenarios":"Calling unsubscribe (UnsubscribeCommand::Instrument) with a synthetic InstrumentId — often during teardown code that unsubscribes everything it ever subscribed, or symmetric subscribe/unsubscribe helpers.","commonSituations":"Cleanup paths that mirror-subscribe all data types; strategy shutdown code iterating over a mixed list of real and synthetic instrument IDs.","solutions":["Skip synthetic instrument IDs in Instrument unsubscribe calls (guard with is_synthetic()).","Track which streams were actually subscribed and unsubscribe only those.","For synthetic data, use the supported unsubscribe path (synthetic Trades) or simply drop the synthetic generator state."],"exampleFix":"// before\nengine.unsubscribe_instruments(synthetic_id)?;\n// after\nif !synthetic_id.is_synthetic() {\n    engine.unsubscribe_instruments(synthetic_id)?;\n}","handlingStrategy":"type-guard","validationCode":"// Rust\nif !instrument_id.is_synthetic() {\n    engine.unsubscribe_instruments(instrument_id)?;\n}","typeGuard":"// Rust\nfn needs_instrument_unsubscribe(id: &InstrumentId) -> bool {\n    !id.is_synthetic()\n}","tryCatchPattern":"// Rust\nmatch engine.unsubscribe_instruments(id) {\n    Err(e) if e.to_string().contains(\"unsubscribe from synthetic instrument `Instrument`\") => Ok(()),\n    r => r,\n}","preventionTips":["Track actual subscriptions and only unsubscribe what was subscribed.","Mirror the same is_synthetic() guard used at subscribe time in teardown code.","Treat synthetic teardown as state cleanup, not client unsubscribes."],"tags":["rust","data-engine","synthetic-instrument","unsubscribe"],"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"}