{"record":{"id":"6e8d6fe2ec020f98","repo":"nautechsystems/nautilus_trader","slug":"failed-to-start-betfair-task-generation-e","errorCode":null,"errorMessage":"Failed to start Betfair task generation: {e}","messagePattern":"Failed to start Betfair task generation: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/betfair/src/execution.rs","lineNumber":1451,"sourceCode":"        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}\"))?;\n\n            let funds: AccountFundsResponse = self\n                .http_client","sourceCodeStart":1433,"sourceCodeEnd":1469,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/betfair/src/execution.rs#L1433-L1469","documentation":"Immediately after starting the session generation, connect starts the pending_tasks generation for order/account requests. If start_generation fails, teardown_partial_connect runs and the error is wrapped with this message.","triggerScenarios":"pending_tasks group not in a startable state — concurrent connects, prior shutdown still in progress, or session generation started but pending generation refused.","commonSituations":"Same lifecycle races as session generation: double connect, reconnect during teardown, half-initialized client after a failed connect.","solutions":["Serialize connect/disconnect calls","Await completion of any previous teardown before reconnecting","Log the inner `e` to identify whether the group was closed or already open"],"exampleFix":"// before: racing reconnect with shutdown\ndisconnect_future.abort();\nclient.connect().await?;\n// after: await teardown first\ndisconnect_future.await.ok();\nclient.connect().await?;","handlingStrategy":"validation","validationCode":"if client.is_connected() { return Ok(()); }","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(\"task generation\") {\n        client.disconnect().await.ok();\n        client.connect().await?;\n    } else { return Err(e); }\n}","preventionTips":["Serialize lifecycle transitions","Let the setup guard (TaskGroupGuard) complete before shutdown","Treat connect as idempotent-guarded in your wrapper"],"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"}