{"record":{"id":"abb56e12b2e34160","repo":"nautechsystems/nautilus_trader","slug":"rtds-connect-was-canceled-by-shutdown","errorCode":null,"errorMessage":"RTDS connect was canceled by shutdown","messagePattern":"RTDS connect was canceled by shutdown","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/adapters/polymarket/src/rtds.rs","lineNumber":552,"sourceCode":"            }\n        }\n\n        self.inner.last_emitted_timestamps_ms.remove(&parsed.key);\n        entry.remove();\n        Ok(true)\n    }\n\n    pub(crate) async fn connect(&self) -> anyhow::Result<()> {\n        let generation = *self.inner.shutdown_generation.lock();\n\n        if self.inner.closing.load(Ordering::Acquire) {\n            self.finish_retained_tasks().await?;\n        }\n\n        {\n            let current_generation = self.inner.shutdown_generation.lock();\n            if *current_generation != generation {\n                anyhow::bail!(\"RTDS connect was canceled by shutdown\");\n            }\n            self.inner.closing.store(false, Ordering::Release);\n        }\n\n        self.ensure_reconcile_worker();\n        self.reconcile_once(false).await?;\n\n        let current_generation = self.inner.shutdown_generation.lock();\n        if *current_generation != generation || self.inner.closing.load(Ordering::Acquire) {\n            anyhow::bail!(\"RTDS connect was canceled by shutdown\");\n        }\n        Ok(())\n    }\n\n    async fn finish_retained_tasks(&self) -> anyhow::Result<()> {\n        let Some(tasks) = self.task_slots() else {\n            if let Some(ws) = self.current_ws() {\n                ws.notify_closed();","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/rtds.rs#L534-L570","documentation":"During RTDS connect, after retained tasks finish, the code checks the shutdown generation counter; if a shutdown happened concurrently (generation advanced), the in-flight connect is stale and is canceled with this error. It prevents a connect from resurrecting resources after shutdown began.","triggerScenarios":"Calling connect() concurrently with shutdown()/disconnect(); a shutdown initiated while a reconnect loop was mid-connect; races from dropping the client while auto-reconnect is active.","commonSituations":"App teardown racing a background reconnect; calling connect from another task right as the client is shut down; rapid connect/disconnect cycles.","solutions":["Stop calling connect() once shutdown has been initiated; check client state first","Serialize connect/shutdown calls (e.g. hold a lock or a single supervision task)","Treat this error as a benign cancellation: log and return instead of retrying"],"exampleFix":"// before\ntokio::join!(client.connect(), async { client.shutdown().await });\n// after\nclient.shutdown().await?;\n// then no further connect() calls on this client instance","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_shutdown_canceled(e: &anyhow::Error) -> bool {\n    e.to_string() == \"RTDS connect was canceled by shutdown\"\n}","tryCatchPattern":"match client.connect().await {\n    Err(e) if e.to_string() == \"RTDS connect was canceled by shutdown\" => {\n        log::info!(\"connect canceled by shutdown; ignoring\");\n    }\n    r => r?,\n}","preventionTips":["Do not call connect() after initiating shutdown","Funnel connect/reconnect through a single supervisor task","Treat this specific error as benign cancellation, not a fault"],"tags":["rust","async","races","shutdown","websocket"],"backgroundTag":"invalid-state-transition","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"}