{"record":{"id":"5fe166c096a1dd40","repo":"nautechsystems/nautilus_trader","slug":"cannot-unsubscribe-from-synthetic-instrument-inst-5fe166","errorCode":null,"errorMessage":"Cannot unsubscribe from synthetic instrument `InstrumentClose` data","messagePattern":"Cannot unsubscribe from synthetic instrument `InstrumentClose` data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/mod.rs","lineNumber":1279,"sourceCode":"                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!(\n                \"Cannot handle command: no client found for client_id={:?}, venue={:?}\",\n                cmd.client_id(),\n                cmd.venue(),\n            );\n        }","sourceCodeStart":1261,"sourceCodeEnd":1297,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/mod.rs#L1261-L1297","documentation":"The DataEngine refuses to process an UnsubscribeCommand for InstrumentClose data when the instrument_id is synthetic (e.g. IDs generated by SyntheticInstrument). Synthetic instruments are computed locally and their data streams are internal, so there is no client/provider subscription to tear down.","triggerScenarios":"Calling DataEngine.unsubscribe with an UnsubscribeCommand::InstrumentClose whose instrument_id.is_synthetic() is true, typically after subscribing to a synthetic instrument's close stream and then unsubscribing by that ID.","commonSituations":"Configuring a synthetic instrument ID (generated via SyntheticInstrument) where a real venue instrument ID is expected; reusing subscription code between synthetic and real instruments; stale subscription bookkeeping from a prior synthetic subscribe.","solutions":["Do not call unsubscribe for InstrumentClose data on a synthetic instrument ID; synthetic data is managed internally","Verify the instrument_id passed to unsubscribe is a real venue instrument (not one produced by SyntheticInstrument)","Guard the call: check instrument_id.is_synthetic() before issuing the unsubscribe command","If cleanup is needed, cancel the synthetic instrument subscription through the synthetic-instrument API instead"],"exampleFix":"// before\nengine.unsubscribe(InstrumentClose::new(synthetic_instrument_id, client_id, venue));\n// after\nif !synthetic_instrument_id.is_synthetic() {\n    engine.unsubscribe(InstrumentClose::new(synthetic_instrument_id, client_id, venue));\n}","handlingStrategy":"validation","validationCode":"if instrument_id.is_synthetic() {\n    // skip unsubscribe; synthetic data is engine-managed\n    return Ok(());\n}","typeGuard":"fn is_real_instrument(id: &InstrumentId) -> bool {\n    !id.is_synthetic()\n}","tryCatchPattern":"match engine.unsubscribe(cmd) {\n    Err(e) if e.to_string().contains(\"synthetic instrument\") => log::warn!(\"skipped synthetic unsubscribe: {e}\"),\n    Err(e) => return Err(e),\n    Ok(_) => {}\n}","preventionTips":["Check is_synthetic() on every instrument ID before subscribe/unsubscribe commands","Keep synthetic and real instrument subscription flows in separate code paths","Log synthetic IDs distinctly so config mistakes surface early"],"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"}