nautechsystems/nautilus_trader · error · anyhow::Error
Failed to terminate Hyperliquid execution session tasks: {e}
Error message
Failed to terminate Hyperliquid execution session tasks: {e} What it means
Raised when the Hyperliquid execution client's session-task group (long-lived WebSocket/session loops) cannot be terminated within the shutdown grace and cancel windows during teardown. It wraps the underlying finish_shutdown error from the TaskGroup.
Source
Thrown at crates/adapters/hyperliquid/src/execution.rs:654
Ok(())
}
async fn await_pending_tasks(&self) -> anyhow::Result<()> {
self.pending_tasks.begin_shutdown();
self.pending_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))
.await
.map_err(|e| anyhow::anyhow!("Failed to terminate Hyperliquid execution tasks: {e}"))?;
Ok(())
}
async fn await_session_tasks(&self) -> anyhow::Result<()> {
self.session_tasks.begin_shutdown();
self.session_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))
.await
.map_err(|e| {
anyhow::anyhow!("Failed to terminate Hyperliquid execution session tasks: {e}")
})?;
Ok(())
}
}
#[async_trait(?Send)]
impl ExecutionClient for HyperliquidExecutionClient {
fn is_connected(&self) -> bool {
self.core.is_connected()
}
fn client_id(&self) -> ClientId {
self.core.client_id
}
fn account_id(&self) -> AccountId {
self.core.account_id
}View on GitHub (pinned to 18893faf8b)
Solutions
- Check that session tasks honor the begin_shutdown signal promptly in their select loops
- Retry teardown after a delay, or treat it as non-fatal and log a warning
- Inspect the wrapped error to identify which session task stalled
- Increase the grace/cancel durations if session loops legitimately need longer to unwind
Example fix
// before
.map_err(|e| anyhow::anyhow!("Failed to terminate Hyperliquid execution session tasks: {e}"))?;
// after
if let Err(e) = self.session_tasks.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2)).await {
log::warn!("session tasks did not terminate cleanly: {e}");
} Defensive patterns
Strategy: try-catch
Validate before calling
if !self.session_tasks.is_open() { self.teardown_partial_connect().await?; } Try / catch
match client.await_session_tasks().await { Err(e) => { log::warn!("session tasks did not terminate: {e}"); /* proceed or retry */ } Ok(_) => {} } Prevention
- Ensure session loops select on the shutdown signal in every await point
- Add timeouts to WS reads so shutdown is observed promptly
- Avoid spawning session tasks outside the managed group
- Test disconnect/reconnect paths under slow-network conditions
When it happens
Trigger: await_session_tasks() is called from teardown_partial_connect() after a failed/partial connect; it errors when session tasks do not stop within Duration::from_secs(1) grace plus Duration::from_secs(2) hard-cancel.
Common situations: A session task blocked awaiting a WebSocket read that ignores the shutdown signal; slow network teardown after a partial connect failure; a session task stuck retrying against an unreachable Hyperliquid endpoint.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- failed to finish Binance Futures data command tasks: {e}
- Binance Futures data teardown failed: {}
- errors.join("; ") (aggregated shutdown errors)
- std::mem::take(&mut self.shutdown_errors).join("; ")
- {context}: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/cb3dd4868585029c.
Report an issue: GitHub.