{"record":{"id":"a88589d5be513cdc","repo":"nautechsystems/nautilus_trader","slug":"hyperliquid-session-task-admission-is-closed-e","errorCode":null,"errorMessage":"Hyperliquid session task admission is closed: {e}","messagePattern":"Hyperliquid session task admission is closed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/hyperliquid/src/execution.rs","lineNumber":1734,"sourceCode":"            self.await_account_registered(30.0).await?;\n\n            Ok::<(), anyhow::Error>(())\n        };\n\n        if let Err(e) = post_ws.await {\n            log::warn!(\"Connect failed after WS started, tearing down: {e}\");\n            if let Err(teardown_error) = self.teardown_partial_connect().await {\n                return Err(e.context(format!(\n                    \"Hyperliquid execution startup teardown failed: {teardown_error}\"\n                )));\n            }\n            return Err(e);\n        }\n\n        let session_spawner = self\n            .session_tasks\n            .spawner()\n            .map_err(|e| anyhow::anyhow!(\"Hyperliquid session task admission is closed: {e}\"))?;\n\n        for parent_id in ready_bracket_parents {\n            if let Some(children) = self.staged_brackets.lock().activate(&parent_id) {\n                spawn_staged_children(\n                    children,\n                    &self.emitter,\n                    &self.ws_client,\n                    &self.http_client,\n                    self.ws_dispatch_state.clone(),\n                    self.staged_brackets.clone(),\n                    self.http_client.builder_attribution(),\n                    self.clock,\n                    &session_spawner,\n                );\n            }\n        }\n\n        if let Err(e) = self.start_outcome_settlement_poll() {","sourceCodeStart":1716,"sourceCodeEnd":1752,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/hyperliquid/src/execution.rs#L1716-L1752","documentation":"Raised in connect() when obtaining a spawner from the session_tasks TaskGroup fails, meaning the group is not admitting new tasks. Without a spawner, the client cannot spawn session tasks or staged bracket children, so connect aborts with this error.","triggerScenarios":"After starting new generations and awaiting setup, connect() calls session_tasks.spawner(); it errors when the group's admission is closed — e.g. shutdown was triggered concurrently (via a setup guard or ws shutdown) or the generation was not actually open.","commonSituations":"Concurrent shutdown racing with connect; a connect attempt against a client already being torn down; the setup guard triggering begin_shutdown (e.g. on setup error) before spawner() is reached.","solutions":["Ensure connect() is not called concurrently with teardown/shutdown of the client","Check for earlier setup errors that triggered the TaskGroupGuard to begin_shutdown","Retry connect after shutdown completes and the group has been reset","Inspect the wrapped error for the TaskGroup's current state"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if client.is_disconnecting() { return; } // don't connect during shutdown","typeGuard":null,"tryCatchPattern":"match client.connect().await { Err(e) if e.to_string().contains(\"admission is closed\") => { wait_for_shutdown_complete(); retry(); }, Err(e) => return Err(e), Ok(_) => {} }","preventionTips":["Serialize connect/teardown operations; never run them concurrently","Handle setup errors before they trip the TaskGroupGuard's begin_shutdown","Check client lifecycle state before connecting","Log guard-triggered shutdowns to diagnose racing connects"],"tags":["rust","task-group","concurrency","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"}