{"record":{"id":"f5461178f8c9365c","repo":"nautechsystems/nautilus_trader","slug":"failed-to-start-betfair-session-generation-e","errorCode":null,"errorMessage":"Failed to start Betfair session generation: {e}","messagePattern":"Failed to start Betfair session generation: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/betfair/src/execution.rs","lineNumber":1448,"sourceCode":"            client.begin_shutdown();\n        }\n\n        self.clear_resync_state();\n        log::info!(\"Stopped: client_id={}\", self.core.client_id);\n        Ok(())\n    }\n\n    async fn connect(&mut self) -> anyhow::Result<()> {\n        if self.core.is_connected() && self.session_tasks.is_open() && self.pending_tasks.is_open()\n        {\n            return Ok(());\n        }\n\n        if !self.session_tasks.is_open() || !self.pending_tasks.is_open() {\n            self.teardown_partial_connect().await?;\n            self.session_tasks\n                .start_generation()\n                .map_err(|e| anyhow::anyhow!(\"Failed to start Betfair session generation: {e}\"))?;\n            self.pending_tasks\n                .start_generation()\n                .map_err(|e| anyhow::anyhow!(\"Failed to start Betfair task generation: {e}\"))?;\n        }\n\n        let http_cancellation = self.http_client.cancellation_token();\n        let setup_guard =\n            TaskGroupGuard::new(&[&self.session_tasks, &self.pending_tasks], move || {\n                http_cancellation.cancel();\n            });\n\n        register_betfair_custom_data();\n\n        let session_token_result = async {\n            self.http_client\n                .connect()\n                .await\n                .map_err(|e| anyhow::anyhow!(\"{e}\"))?;","sourceCodeStart":1430,"sourceCodeEnd":1466,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/betfair/src/execution.rs#L1430-L1466","documentation":"connect (execution client) starts a new task generation for session_tasks. If start_generation fails (e.g. the group is still shutting down or the generation is already open), teardown_partial_connect is invoked first and the error is wrapped with this message.","triggerScenarios":"session_tasks or pending_tasks group is not open (mid-shutdown or never initialized) and start_generation still fails — concurrent connect calls, or a prior connect's teardown not yet finished.","commonSituations":"Calling connect twice without disconnect; reconnect racing a prior shutdown; a previous failed connect leaving the groups in a half-open state.","solutions":["Ensure connect/disconnect calls are strictly sequential","Wait for teardown_partial_connect of the previous attempt to finish before reconnecting","Inspect the inner error `e` from start_generation for the registry state"],"exampleFix":"// before: overlapping connects\ntokio::join!(client.connect(), client.connect());\n// after\nclient.connect().await?;\n// later\nclient.disconnect().await?;\nclient.connect().await?;","handlingStrategy":"validation","validationCode":"if client.is_connected() { return Ok(()); } // avoid double connect","typeGuard":"fn can_connect(client: &BetfairExecClient) -> bool {\n    !client.is_connected() && !client.is_shutting_down()\n}","tryCatchPattern":"if let Err(e) = client.connect().await {\n    if e.to_string().contains(\"session generation\") {\n        tokio::time::sleep(Duration::from_secs(1)).await;\n        client.connect().await?;\n    } else { return Err(e); }\n}","preventionTips":["Use a mutex/flag so connect runs once","Always run teardown to completion before reconnect","Avoid spawning connect and disconnect concurrently"],"tags":["rust","betfair","lifecycle","task-group","reconnect"],"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-14T05:17:10.506Z"}