{"record":{"id":"2f1f3016af1f1160","repo":"nautechsystems/nautilus_trader","slug":"failed-to-serialize-unsubscription-e","errorCode":null,"errorMessage":"Failed to serialize unsubscription: {e}","messagePattern":"Failed to serialize unsubscription: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/websocket/handler.rs","lineNumber":561,"sourceCode":"        Ok(())\n    }\n\n    async fn handle_unsubscribe(&self, args: Vec<OKXSubscriptionArg>) -> anyhow::Result<()> {\n        for arg in &args {\n            log::debug!(\n                \"Unsubscribing from channel: channel={:?}, inst_id={:?}\",\n                arg.channel,\n                arg.inst_id\n            );\n        }\n\n        let message = OKXSubscription {\n            op: OKXWsOperation::Unsubscribe,\n            args,\n        };\n\n        let json_txt = serde_json::to_string(&message)\n            .map_err(|e| anyhow::anyhow!(\"Failed to serialize unsubscription: {e}\"))?;\n\n        self.send_with_retry(json_txt, Some(OKX_RATE_LIMIT_KEY_SUBSCRIPTION.as_slice()))\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to send unsubscription after retries: {e}\"))?;\n        Ok(())\n    }\n\n    pub(crate) fn parse_raw_message(\n        msg: tokio_tungstenite::tungstenite::Message,\n    ) -> Option<OKXWsFrame> {\n        match msg {\n            tokio_tungstenite::tungstenite::Message::Text(text) => {\n                if text == TEXT_PONG {\n                    log::trace!(\"Received pong from OKX\");\n                    return None;\n                }\n\n                if text == TEXT_PING {","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/websocket/handler.rs#L543-L579","documentation":"`handle_unsubscribe` serializes the OKXSubscription (op=unsubscribe) to JSON before sending. If `serde_json::to_string` fails, the error is wrapped with this message. As with subscribe, this is near-impossible with well-formed typed args.","triggerScenarios":"`serde_json::to_string(&OKXSubscription{op: Unsubscribe, args})` returns Err during handle_unsubscribe — malformed or unserializable unsubscribe args.","commonSituations":"Programmatically constructed unsubscribe args containing invalid values; virtually never seen with the adapter's normal unsubscribe API.","solutions":["Check the inner `{e}` and the args passed; ensure channel/inst_id values are plain strings.","Use the adapter's public unsubscribe API rather than hand-building OKXSubscriptionArg values.","Report as a bug if it reproduces with standard args."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the adapter's public unsubscribe API with standard channel identifiers.","Avoid hand-building OKXSubscriptionArg values.","Treat occurrences as library bugs and file a report."],"tags":["websocket","okx","serialization","unsubscribe"],"backgroundTag":"json-marshal-failed","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"}