{"record":{"id":"6f91af9043986a81","repo":"nautechsystems/nautilus_trader","slug":"derive-session-task-admission-is-closed-e","errorCode":null,"errorMessage":"Derive session task admission is closed: {e}","messagePattern":"Derive session task admission is closed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/derive/src/execution.rs","lineNumber":454,"sourceCode":"        }\n        Ok(())\n    }\n\n    fn start_ws_dispatch(\n        &self,\n        rx: tokio::sync::mpsc::UnboundedReceiver<DeriveWsMessage>,\n    ) -> anyhow::Result<()> {\n        let emitter = self.emitter.clone();\n        let account_id = self.core.account_id;\n        let clock = self.clock;\n        let cancellation = self.cancellation_token.clone();\n        let dispatch_state = self.dispatch_state.clone();\n        let reconciliation = self.reconciliation_context();\n        let is_connected = Arc::clone(&self.is_connected);\n        let session_spawner = self\n            .session_tasks\n            .spawner()\n            .map_err(|e| anyhow::anyhow!(\"Derive session task admission is closed: {e}\"))?;\n\n        self.session_tasks.spawn(async move {\n            let mut rx = rx;\n\n            loop {\n                tokio::select! {\n                    biased;\n                    () = cancellation.cancelled() => break,\n                    maybe = rx.recv() => {\n                        match maybe {\n                            Some(DeriveWsMessage::Reconnected) => {\n                                let context = reconciliation.clone();\n                                let task_cancellation = cancellation.clone();\n\n                                if let Err(e) = session_spawner.spawn(async move {\n                                    tokio::select! {\n                                        () = task_cancellation.cancelled() => {}\n                                        result = context.recover_after_reconnect() => {","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/derive/src/execution.rs#L436-L472","documentation":"start_ws_dispatch obtains a spawner from the session_tasks TaskGroup to spawn the WS message dispatch loop. If the TaskGroup's admission is closed (the group is shutting down or not open), spawner() fails and the error is wrapped with this message. It means the client tried to start dispatch while its session task group could no longer accept new tasks.","triggerScenarios":"Calling connect (which invokes start_ws_dispatch) on a Derive execution client whose session_tasks group is already closed/shutting down — e.g. connect after disconnect, or racing connect against shutdown.","commonSituations":"Calling connect concurrently with stop/disconnect; reconnect logic firing after the client was halted; lifecycle misuse where connect is invoked on a disposed client instance.","solutions":["Only call connect while the client is stopped-but-not-shut-down; ensure disconnect/stop has fully reset the task groups before reconnecting, or recreate the client.","Guard against concurrent connect/stop calls with proper lifecycle management.","Check the inner TaskGroup error to confirm the group's state (closed vs already started).","If reconnect support is needed, use the client's supported reconnect path rather than calling connect after teardown."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Do not call connect if the group is closing:\nif client.is_shutting_down() { return Err(\"cannot connect during shutdown\".into()); }","typeGuard":null,"tryCatchPattern":"match exec_client.connect().await {\n    Ok(()) => (),\n    Err(e) if e.to_string().contains(\"admission is closed\") => {\n        // recreate the client; its task groups are closed\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Call connect exactly once per client lifecycle; recreate the client for reconnects","Serialize connect/stop calls under a single owner or mutex","Never invoke connect concurrently with disconnect/stop"],"tags":["derive","task-group","lifecycle","connect","rust"],"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"}