{"record":{"id":"3aec00490a761aef","repo":"nautechsystems/nautilus_trader","slug":"cannot-unsubscribe-from-synthetic-instrument-inst-3aec00","errorCode":null,"errorMessage":"Cannot unsubscribe from synthetic instrument `InstrumentStatus` data","messagePattern":"Cannot unsubscribe from synthetic instrument `InstrumentStatus` data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/mod.rs","lineNumber":1274,"sourceCode":"            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()) {\n            client.execute_unsubscribe(cmd);\n        } else {\n            log::error!(","sourceCodeStart":1256,"sourceCodeEnd":1292,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/mod.rs#L1256-L1292","documentation":"InstrumentStatus subscriptions never exist for synthetic instruments, so the corresponding unsubscribe is likewise impossible. UnsubscribeCommand::InstrumentStatus with a synthetic instrument ID is rejected with this error.","triggerScenarios":"Calling unsubscribe for InstrumentStatus where the InstrumentId is synthetic (is_synthetic() == true), e.g. blanket teardown loops unsubscribing all data types for all instruments.","commonSituations":"Strategy shutdown routines that unsubscribe every stream type unconditionally; refactors that changed an instrument ID to a synthetic one without updating subscription bookkeeping.","solutions":["Guard InstrumentStatus unsubscribes with an is_synthetic() check and skip synthetic IDs.","Maintain a record of live subscriptions and only issue matching unsubscribes.","Resolve the mismatch if synthetic IDs unexpectedly appear in your real-instrument teardown list."],"exampleFix":"// before\nfor id in &instrument_ids {\n    engine.unsubscribe_instrument_status(*id)?;\n}\n// after\nfor id in instrument_ids.iter().filter(|id| !id.is_synthetic()) {\n    engine.unsubscribe_instrument_status(*id)?;\n}","handlingStrategy":"type-guard","validationCode":"// Rust\nif !instrument_id.is_synthetic() {\n    engine.unsubscribe_instrument_status(instrument_id)?;\n}","typeGuard":"// Rust\nfn was_ever_subscribed(id: &InstrumentId, cmd: &UnsubscribeCommand) -> bool {\n    !id.is_synthetic() // InstrumentStatus is never subscribed for synthetics\n}","tryCatchPattern":"// Rust\nif let Err(e) = engine.unsubscribe_instrument_status(id) {\n    if e.to_string().contains(\"unsubscribe from synthetic instrument `InstrumentStatus`\") {\n        log::debug!(\"no InstrumentStatus subscription existed for synthetic {id}\");\n    } else {\n        return Err(e.into());\n    }\n}","preventionTips":["Keep a subscription ledger and unsubscribe only recorded subscriptions.","Apply the is_synthetic() filter consistently in both subscribe and unsubscribe paths.","Make teardown loops resilient: log-and-continue on unsupported unsubscribe targets."],"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-14T05:17:10.506Z"}