nautechsystems/nautilus_trader · error
WebSocket output receiver not available
Error message
WebSocket output receiver not available
What it means
During CoinbaseDataAdapter startup, spawn_ws consumes the WebSocket client's output receiver channel exactly once (take_out_rx). If the receiver is already taken or was never created, the adapter rolls back the just-established WebSocket connection and aborts the connect flow. This is an internal lifecycle guard against a double-consumed WS stream.
Source
Thrown at crates/adapters/coinbase/src/data/mod.rs:265
self.ws_client.update_instrument(instrument.clone()).await;
}
log::debug!("Bootstrapped {} instruments", instruments.len());
Ok(instruments)
}
async fn spawn_ws(&mut self) -> anyhow::Result<()> {
self.ws_client
.connect()
.await
.context("failed to connect to Coinbase WebSocket")?;
let Some(mut out_rx) = self.ws_client.take_out_rx() else {
self.ws_client
.disconnect()
.await
.context("failed to roll back Coinbase WebSocket without output receiver")?;
anyhow::bail!("WebSocket output receiver not available");
};
let data_sender = self.data_sender.clone();
let cancellation_token = self.cancellation_token.clone();
let status_subs = Arc::clone(&self.instrument_status_subs);
let future = async move {
log::debug!("Coinbase WebSocket consumption loop started");
loop {
tokio::select! {
() = cancellation_token.cancelled() => {
log::debug!("WebSocket consumption loop cancelled");
break;
}
msg_opt = out_rx.recv() => {
match msg_opt {
Some(msg) => dispatch_ws_message(msg, &data_sender, &status_subs),View on GitHub (pinned to 18893faf8b)
Solutions
- Create a fresh adapter/WS client for each connect() call instead of reconnecting on a used instance
- Ensure only one consumer calls take_out_rx; do not share the ws_client across concurrent connect paths
- Check that any prior connect attempt fully tore down (disconnect) before reconnecting, and recreate channels
- Inspect logs for the 'failed to roll back Coinbase WebSocket' context to confirm the rollback succeeded
Example fix
// before let mut adapter = CoinbaseDataClientFactory::create(...); adapter.connect().await?; adapter.disconnect().await?; adapter.connect().await?; // receiver already taken // after let mut adapter = CoinbaseDataClientFactory::create(...); adapter.connect().await?; adapter.disconnect().await?; let mut adapter = CoinbaseDataClientFactory::create(...); // fresh client/channel adapter.connect().await?;
Defensive patterns
Strategy: try-catch
Validate before calling
// before connect: ensure a fresh client assert!(!adapter.is_connected(), "adapter already connected; recreate it");
Try / catch
match adapter.connect().await {
Err(e) if e.to_string().contains("output receiver not available") => {
// recreate the adapter/WS client and retry once
}
other => other?,
} Prevention
- Treat connect() as one-shot: construct a new client per connection cycle
- Never share one Coinbase ws_client across two consumers
- Always disconnect() and rebuild before reconnecting
- Watch for double-spawn of the data task in reconnect loops
When it happens
Trigger: Calling connect (via spawn_ws) twice without recreating the adapter's WebSocket client, or constructing the adapter with a ws_client whose output channel was already consumed by another spawn_ws call.
Common situations: Reconnect logic that reuses a stale adapter/WS client after a previous connect; spawning two data tasks sharing one adapter; tests or scripts that call connect() repeatedly on the same instance.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- std::mem::take(&mut self.shutdown_errors).join("; ")
- std::mem::take(&mut self.shutdown_errors).join("; ")
- Coinbase WebSocket handler failed: {error}
- Failed to connect to {} after {} attempts: {}. If this is a
- Failed to start Binance Spot session generation: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7383cc7fdc500957.
Report an issue: GitHub.