{"record":{"id":"8a6661ca49955250","repo":"nautechsystems/nautilus_trader","slug":"failed-to-start-betfair-data-session-tasks-e","errorCode":null,"errorMessage":"Failed to start Betfair data session tasks: {e}","messagePattern":"Failed to start Betfair data session tasks: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/betfair/src/data.rs","lineNumber":239,"sourceCode":"        let (session_result, command_result) = tokio::join!(\n            self.session_tasks\n                .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2)),\n            self.command_tasks\n                .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2)),\n        );\n        session_result\n            .map_err(|e| anyhow::anyhow!(\"Failed to finish Betfair data session tasks: {e}\"))?;\n        command_result\n            .map_err(|e| anyhow::anyhow!(\"Failed to finish Betfair data command tasks: {e}\"))?;\n        Ok(())\n    }\n\n    async fn prepare_task_groups(&mut self) -> anyhow::Result<()> {\n        if !self.session_tasks.is_open() || !self.command_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 data session tasks: {e}\"))?;\n            self.command_tasks\n                .start_generation()\n                .map_err(|e| anyhow::anyhow!(\"Failed to start Betfair data command tasks: {e}\"))?;\n        }\n        Ok(())\n    }\n\n    fn begin_stream_shutdown(&self) {\n        for stream in self.stream_shutdowns.lock().iter() {\n            stream.begin_shutdown();\n        }\n    }\n\n    async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {\n        self.session_tasks.begin_shutdown();\n        self.command_tasks.begin_shutdown();\n        self.begin_stream_shutdown();\n        self.is_connected.store(false, Ordering::Relaxed);","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/betfair/src/data.rs#L221-L257","documentation":"This error wraps a failure from session_tasks.start_generation() in prepare_task_groups, which reopens the session TaskGroup before (re)connecting the Betfair data client. Task groups are one-shot per generation: after a shutdown they must be restarted to spawn new tasks. If start_generation returns Err, the adapter cannot begin a new connect lifecycle.","triggerScenarios":"connect() -> prepare_task_groups sees session_tasks.is_open() == false (group was shut down by a previous disconnect or failed connect), calls teardown_partial_connect, then start_generation() fails. Typically when the group state does not permit restarting a generation (already running, or shutdown not fully finalized).","commonSituations":"Rapid reconnect sequences where teardown did not fully complete before the next connect; concurrent connect calls on the same adapter; a prior finish_shutdown failure leaving the group in an inconsistent state.","solutions":["Ensure teardown_partial_connect fully completes (including finish_tasks) before attempting connect again","Check the inner `{e}` from start_generation to determine the offending TaskGroup state","Avoid concurrent or overlapping connect() calls on the same BetfairDataClient instance","Recreate the data client if the task group cannot be restarted after repeated failures"],"exampleFix":"// before\nself.session_tasks.start_generation().map_err(|e| anyhow::anyhow!(\"Failed to start Betfair data session tasks: {e}\"))?;\n// after\nif !self.session_tasks.is_open() {\n    self.session_tasks.start_generation().map_err(|e| anyhow::anyhow!(\"Failed to start Betfair data session tasks: {e}\"))?;\n}","handlingStrategy":"retry","validationCode":"// before reconnecting, ensure the client is fully disconnected\nassert!(!client.is_connected(), \"previous connect still active\");","typeGuard":null,"tryCatchPattern":"match client.connect().await {\n    Err(e) if e.to_string().contains(\"Failed to start Betfair data session tasks\") => {\n        tokio::time::sleep(Duration::from_secs(2)).await;\n        client.disconnect().await.ok(); // force clean teardown, then retry\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {},\n}","preventionTips":["Never call connect() concurrently on the same Betfair data client","Always await disconnect() to completion before reconnecting","Back off between reconnect attempts (2s+) so teardown can finalize","Rebuild the client if repeated start_generation failures occur"],"tags":["rust","async","task-group","reconnect","lifecycle"],"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"}