nautechsystems/nautilus_trader · error

{e}

Error message

{e}

What it means

ws_symbol_op runs a per-symbol websocket operation (subscribe/unsubscribe) and maps any error from the underlying WS call into an anyhow error via anyhow::anyhow!(e), which spawn_ws then propagates. The message is the inner error's display text, so it surfaces whatever the websocket operation failed with.

Source

Thrown at crates/adapters/architect_ax/src/data.rs:307

        clippy::unnecessary_wraps,
        reason = "callers forward Result to trait methods"
    )]
    fn ws_symbol_op<F, Fut>(
        &self,
        instrument_id: InstrumentId,
        op: F,
        context: &'static str,
    ) -> anyhow::Result<()>
    where
        F: FnOnce(AxMdWebSocketClient, String) -> Fut + Send + 'static,
        Fut: Future<Output = Result<(), AxWsClientError>> + Send,
    {
        let symbol = instrument_id.symbol.to_string();
        log::debug!("{context} for {symbol}");

        let ws = self.ws_client.clone();
        self.spawn_ws(
            async move { op(ws, symbol).await.map_err(|e| anyhow::anyhow!(e)) },
            context,
        );

        Ok(())
    }

    fn spawn_ws<F>(&self, fut: F, context: &'static str)
    where
        F: Future<Output = anyhow::Result<()>> + Send + 'static,
    {
        let future = async move {
            if let Err(e) = fut.await {
                log::error!("{context}: {e:?}");
            }
        };

        if let Err(e) = self.pending_tasks.spawn(future) {
            log::warn!("Skipping AX {context} after shutdown began: {e}");

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the data client is connected before subscribing (check is_connected / await connect)
  2. Verify the instrument_id symbol is valid on AX and matches AX symbol conventions
  3. Retry the subscription; check the inner error text for the root cause (auth, network, symbol)
  4. Inspect ws client logs for the underlying transport failure

Example fix

// before
client.subscribe_quotes(instrument_id)?;
// after
if !client.is_connected().await { client.connect().await?; }
client.subscribe_quotes(instrument_id)?;
Defensive patterns

Strategy: retry

Validate before calling

// Rust
if !client.is_connected().await { client.connect().await?; }
// validate symbol exists on AX before subscribing

Try / catch

// Rust
for attempt in 0..3 {
    match client.subscribe_quotes(instrument_id).await {
        Ok(()) => break,
        Err(e) if attempt < 2 => tokio::time::sleep(backoff(attempt)).await,
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Any of subscribe_quotes, subscribe_trades, subscribe_mark_prices, subscribe_instrument_status, unsubscribe_book_deltas, or unsubscribe_quotes when the underlying ws op fails — e.g. the websocket is disconnected, the symbol is rejected by AX, or the send times out.

Common situations: Calling subscribe before connect completes or after disconnect; subscribing to an unsupported/invalid symbol; network drop mid-subscription; AX rejecting an unparseable symbol string.

Related errors


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