{"record":{"id":"115ffc620555b6d4","repo":"nautechsystems/nautilus_trader","slug":"polymarket-websocket-startup-rollback-failed-shu","errorCode":null,"errorMessage":"Polymarket WebSocket startup rollback failed: {shutdown_error}","messagePattern":"Polymarket WebSocket startup rollback failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/lifecycle.rs","lineNumber":404,"sourceCode":"                                }\n                            }\n                        };\n\n                        if let Err(e) = session_spawner.spawn(future) {\n                            log::debug!(\"Skipping reconnect refresh during shutdown: {e}\");\n                        }\n                    }\n                    None => {\n                        log::debug!(\"User WebSocket stream ended\");\n                        break;\n                    }\n                }\n            }\n\n            log::debug!(\"User WebSocket handler task completed\");\n        }) {\n            if let Err(shutdown_error) = self.ws_client.disconnect().await {\n                return Err(anyhow::Error::new(e).context(format!(\n                    \"Polymarket WebSocket startup rollback failed: {shutdown_error}\"\n                )));\n            }\n            return Err(e.into());\n        }\n\n        Ok(())\n    }\n\n    async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {\n        self.stopping.store(true, Ordering::Release);\n        self.clear_order_event_subscription();\n        self.clear_position_event_subscription();\n        self.abort_session_tasks();\n        self.abort_pending_tasks();\n        self.ws_client.begin_shutdown();\n\n        if let Err(e) = self.ws_client.disconnect().await {","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/lifecycle.rs#L386-L422","documentation":"During Polymarket WebSocket startup (start_ws_stream, invoked from connect_client), if the spawned user-stream handler task fails immediately, the client attempts a rollback via ws_client.disconnect(). If that rollback disconnect ALSO fails, the original error is re-wrapped with \"Polymarket WebSocket startup rollback failed: {shutdown_error}\" so both failures are visible. It signals a broken WebSocket lifecycle where neither start nor clean teardown succeeded.","triggerScenarios":"Calling connect on a Polymarket execution/data client where the user WebSocket handler task errors during startup (auth failure, bad URL, network error) and the subsequent disconnect() call also errors (e.g. socket already broken, internal state inconsistent).","commonSituations":"Invalid or missing Polymarket WebSocket credentials; unreachable host / DNS failure during startup; calling connect while a previous connection is half-torn-down; aggressive reconnect loops compounding state corruption.","solutions":["Fix the ORIGINAL startup error (first error in the anyhow chain) — the rollback message is secondary.","Check Polymarket WS credentials and endpoint URL configuration.","Verify network reachability of the Polymarket WebSocket host.","Ensure the client is fully dropped/recreated rather than reused after a failed connect.","Add backoff between reconnect attempts so state can settle before reconnecting."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// validate WS config before connect\nassert!(!ws_url.is_empty() && ws_url.starts_with(\"wss://\"), \"valid WS URL\");\nassert!(credentials_present(), \"API credentials configured\");","typeGuard":null,"tryCatchPattern":"match client.connect().await {\n    Ok(()) => {}\n    Err(e) => {\n        error!(\"connect failed (incl. rollback): {e:#}\");\n        drop(client); // discard possibly-corrupt client state\n        let mut fresh = new_client(config)?;\n        backoff_retry(|| fresh.connect()).await?;\n    }\n}","preventionTips":["Fix the original startup error first; the rollback message is secondary","Recreate the client after a failed connect instead of reusing it","Validate WS URL and credentials before connecting","Use exponential backoff between reconnect attempts"],"tags":["polymarket","websocket","startup","rollback","connection"],"backgroundTag":"connection-refused","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"}