{"record":{"id":"cf0a6e5697191ee4","repo":"nautechsystems/nautilus_trader","slug":"cannot-unsubscribe-from-synthetic-instrument-opti","errorCode":null,"errorMessage":"Cannot unsubscribe from synthetic instrument `OptionGreeks` data","messagePattern":"Cannot unsubscribe from synthetic instrument `OptionGreeks` data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/mod.rs","lineNumber":1284,"sourceCode":"            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!(\n                \"Cannot handle command: no client found for client_id={:?}, venue={:?}\",\n                cmd.client_id(),\n                cmd.venue(),\n            );\n        }\n\n        Ok(())\n    }\n\n    /// Sends a [`RequestCommand`] to a suitable data client implementation.","sourceCodeStart":1266,"sourceCodeEnd":1302,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/mod.rs#L1266-L1302","documentation":"The DataEngine rejects unsubscribing from OptionGreeks data for a synthetic instrument ID. OptionGreeks streams for synthetic instruments are computed locally, so no downstream client subscription exists and the unsubscribe command is invalid.","triggerScenarios":"Calling DataEngine.unsubscribe with UnsubscribeCommand::OptionGreeks where cmd.instrument_id.is_synthetic() is true — i.e. an ID minted by SyntheticInstrument rather than a venue-listed option ID.","commonSituations":"Passing a synthetic option ID built from a synthetic underlying into greeks subscription management; generic unsubscribe loops that iterate all active subscriptions including synthetic ones.","solutions":["Skip the unsubscribe call for synthetic instrument IDs (synthetic greeks are engine-computed)","Check instrument_id.is_synthetic() before constructing the OptionGreeks unsubscribe command","Use a real exchange-listed option instrument ID when unsubscribing from venue greeks data","Manage synthetic greeks lifecycle through the SyntheticInstrument API instead"],"exampleFix":"// before\nfor id in active_ids {\n    engine.unsubscribe(OptionGreeks::new(id, client_id, venue));\n}\n// after\nfor id in active_ids.into_iter().filter(|id| !id.is_synthetic()) {\n    engine.unsubscribe(OptionGreeks::new(id, client_id, venue));\n}","handlingStrategy":"validation","validationCode":"if instrument_id.is_synthetic() {\n    return Ok(()); // synthetic greeks lifecycle is engine-managed\n}","typeGuard":"fn is_venue_instrument(id: &InstrumentId) -> bool {\n    !id.is_synthetic()\n}","tryCatchPattern":"if let Err(e) = engine.unsubscribe(cmd) {\n    if e.to_string().contains(\"synthetic\") { log::debug!(\"ignoring: {e}\"); }\n    else { return Err(e); }\n}","preventionTips":["Filter synthetic IDs out of bulk unsubscribe loops","Use SyntheticInstrument drop/cancel APIs for synthetic greeks","Validate instrument IDs at config load time"],"tags":["rust","data-engine","synthetic-instrument","option-greeks"],"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"}