nautechsystems/nautilus_trader · error

Lighter WebSocket handler did not stop after abort

Error message

Lighter WebSocket handler did not stop after abort

What it means

Raised by connect_with_cancellation when the WebSocket handler task neither completed, aborted cleanly, nor failed after an abort signal was sent — the join returned TaskJoinOutcome::Incomplete. The library treats a handler that ignores abort as a hard startup failure and bails instead of returning a half-connected client.

Source

Thrown at crates/adapters/lighter/src/websocket/client.rs:442

        if self.is_active() {
            log::warn!("Lighter WebSocket already connected");
            return Ok(());
        }

        if let Some(outcome) = finish_task(
            &mut self.task_handle,
            DISCONNECT_TIMEOUT,
            DISCONNECT_TIMEOUT,
        )
        .await
        {
            match outcome {
                TaskJoinOutcome::Completed(()) | TaskJoinOutcome::Aborted => {}
                TaskJoinOutcome::Failed(error) => {
                    anyhow::bail!("Lighter WebSocket handler failed: {error}");
                }
                TaskJoinOutcome::Incomplete => {
                    anyhow::bail!("Lighter WebSocket handler did not stop after abort");
                }
            }
        }

        self.signal.store(false, Ordering::Release);
        self.initial_connect_cancellation
            .store(Arc::new(cancellation_token.clone()));

        let (message_handler, raw_rx) = channel_epoch_message_handler();
        let cfg = WebSocketConfig {
            url: self.url.clone(),
            headers: vec![],
            heartbeat_interval_secs: Some(HEARTBEAT_INTERVAL.as_secs()),
            heartbeat_payload: None,
            connect_timeout_ms: Some(self.ws_timeout_secs.saturating_mul(1_000).max(1)),
            reconnect_delay_initial_ms: Some(RECONNECT_BASE_BACKOFF.as_millis() as u64),
            reconnect_delay_max_ms: Some(RECONNECT_MAX_BACKOFF.as_millis() as u64),
            reconnect_backoff_factor: Some(RECONNECT_BACKOFF_FACTOR),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check network path to the Lighter WebSocket endpoint — a hung/unresponsive connection is the usual cause; fix connectivity or timeout settings.
  2. Increase ws_timeout_secs if the endpoint is slow, so the handler has more time before the join/abort logic runs.
  3. Restart the data client / node; this error usually means a stuck task that won't recover on its own.
  4. Upgrade the adapter/transport crates in case of a known cancellation-handling bug.
  5. Report with debug logs if reproducible — a handler that ignores abort indicates a task-loop bug.

Example fix

// before: default timeout too tight for a slow endpoint
let client = LighterWsClient::connect(..., /*ws_timeout_secs*/ 5).await?;

// after: allow more time before the abort/join path is exercised
let client = LighterWsClient::connect(..., /*ws_timeout_secs*/ 30).await?;
Defensive patterns

Strategy: try-catch

Try / catch

match client.connect().await {
    Err(e) if e.to_string().contains("did not stop after abort") => {
        log::error!("handler wedged; restarting client");
        client = build_ws_client(cfg)?; // rebuild rather than reuse
        client.connect().await?;
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling connect() when the spawned handler task does not terminate in response to the abort signal during initial connection setup — e.g. the task is stuck awaiting a socket operation that does not observe cancellation.

Common situations: A wedged TCP connection to Lighter where the handler's select loop does not poll the abort token; pathological network conditions (black-holed connections); a bug or very old version of the underlying websocket transport that ignores cancellation.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/5cc72778f245f305. Report an issue: GitHub.