{"record":{"id":"e4bc145d16a9dc21","repo":"nautechsystems/nautilus_trader","slug":"failed-to-register-tardis-stream-task-e","errorCode":null,"errorMessage":"failed to register Tardis stream task: {e}","messagePattern":"failed to register Tardis stream task: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/tardis/src/data.rs","lineNumber":252,"sourceCode":"                    Err(e) => {\n                        if cancel.is_cancelled() {\n                            break;\n                        }\n\n                        log::warn!(\n                            \"Failed to reconnect to Tardis Machine: {e}, retrying in {}s\",\n                            reconnect_delay.as_secs()\n                        );\n                    }\n                }\n            }\n\n            connected.store(false, Ordering::Release);\n        };\n\n        self.tasks\n            .spawn(future)\n            .map_err(|e| anyhow::anyhow!(\"failed to register Tardis stream task: {e}\"))?;\n        Ok(())\n    }\n\n    /// Runs a single WebSocket session: starts heartbeat, processes messages,\n    /// and returns whether the caller should attempt reconnection.\n    async fn run_ws_session(\n        ws_stream: tokio_tungstenite::WebSocketStream<\n            tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>,\n        >,\n        cancel: &CancellationToken,\n        sender: &tokio::sync::mpsc::UnboundedSender<DataEvent>,\n        instrument_map: &AHashMap<TardisInstrumentKey, Arc<TardisInstrumentMiniInfo>>,\n        book_snapshot_output: &BookSnapshotOutput,\n        extract_bbo_as_quotes: bool,\n    ) -> bool {\n        let (mut writer, mut reader) = ws_stream.split();\n\n        let heartbeat_token = cancel.child_token();","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/tardis/src/data.rs#L234-L270","documentation":"Raised in spawn_ws_task when the actor task set refuses to register the Tardis WebSocket stream task. It means the task manager (generation-based supervisor) is not in a state that accepts new tasks — typically it is shutting down or the generation has ended.","triggerScenarios":"Calling connect which invokes spawn_ws_task while the task set is finishing shutdown, already closed, or between generations, so tasks.spawn(future) fails.","commonSituations":"Calling connect() concurrently with disconnect(); reconnecting immediately after disconnect before shutdown completes; racing connect calls from multiple threads.","solutions":["Ensure disconnect() has fully completed (finish_shutdown awaited) before calling connect again.","Avoid concurrent connect/disconnect calls; serialize lifecycle operations.","Check that a prior shutdown didn't leave the task set closed; recreate/restart the client if so.","Retry the connect after the task set starts a new generation."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Only connect when fully disconnected and not shutting down\nif client.is_connected.load(Ordering::Acquire) || shutdown_in_progress() {\n    anyhow::bail!(\"cannot connect: client busy or shutting down\");\n}","typeGuard":null,"tryCatchPattern":"match client.connect() {\n    Err(e) if e.to_string().contains(\"failed to register Tardis stream task\") => {\n        tokio::time::sleep(Duration::from_millis(200)).await;\n        client.connect().await?; // retry after shutdown settles\n    }\n    other => other?,\n}","preventionTips":["Await disconnect() completion before reconnecting.","Guard connect/disconnect with a mutex or actor message to prevent races.","Never share a client instance across concurrent lifecycle callers."],"tags":["websocket","task-spawn","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-14T00:17:10.932Z"}