nautechsystems/nautilus_trader · error · anyhow::Error
failed to send RTDS {action} request: {e}
Error message
failed to send RTDS {action} request: {e} What it means
The RTDS client sends subscription/request payloads over the WebSocket via ws.send_text; when the send fails, it wraps the underlying WebSocketClient error as 'failed to send RTDS {action} request: {e}'. It means the control-plane message for the given action (e.g. subscribe/auth) never reached Polymarket's RTDS gateway.
Source
Thrown at crates/adapters/polymarket/src/rtds.rs:1099
async fn send_wire_request(
&self,
ws: &Arc<WebSocketClient>,
action: &'static str,
subscriptions: Vec<RtdsWireSubscription>,
) -> anyhow::Result<()> {
if subscriptions.is_empty() {
return Ok(());
}
let request = RtdsWireRequest {
action,
subscriptions,
};
let payload = serde_json::to_string(&request)?;
ws.send_text(payload, None)
.await
.map_err(|e| anyhow::anyhow!("failed to send RTDS {action} request: {e}"))
}
async fn run_message_loop(
&self,
ws: Arc<WebSocketClient>,
mut raw_rx: tokio::sync::mpsc::UnboundedReceiver<Message>,
) {
loop {
match raw_rx.recv().await {
Some(Message::Text(text)) => {
if text.as_str() == RECONNECTED {
log::info!("Polymarket RTDS reconnected");
self.request_reconcile(ReconcileReason::TransportReset);
continue;
}
if text.as_str() == "PONG" {
continue;View on GitHub (pinned to 18893faf8b)
Solutions
- Retry after the connection is re-established; RTDS reconnect logic typically resubscribes automatically
- Check the inner error (after ': {e}') to distinguish closed socket vs write failure
- Verify the RTDS endpoint is reachable and the socket is connected before sending requests
- Inspect auth state — servers often close sockets after auth expiry, making the next send fail
Example fix
// before
ws.send_text(payload, None).await?;
// after
if !ws.is_connected() { reconnect().await?; }
ws.send_text(payload, None).await
.map_err(|e| { warn!("RTDS {action} send failed: {e:#}"); e })?; Defensive patterns
Strategy: retry
Try / catch
// Rust
match send_rtds_request(action, subscriptions).await {
Err(e) if e.to_string().contains("failed to send RTDS") => {
reconnect().await?;
send_rtds_request(action, subscriptions).await?;
}
other => other?,
} Prevention
- Check connection state before sending RTDS control messages
- Rely on the adapter's resubscribe-on-reconnect flow instead of manual sends on stale sockets
- Watch auth expiry — servers close sockets after it, making subsequent sends fail
When it happens
Trigger: Calling the RTDS request-sending path while the WebSocket connection is closed, dropped, or the outbound channel is full/closed — the serde_json::to_string of the request succeeded but transport failed.
Common situations: Network outage mid-session, server closing the socket after auth failure, attempting to (re)subscribe on a dead connection, or sending before the connection handshake finished.
Related errors
- unsupported subscribed RTDS message topic={topic} type={msg_
- invalid RTDS crypto TWAP payload: {e}
- invalid RTDS JSON frame
- Binance Futures data teardown failed: {}
- Binance Spot data teardown failed: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1dac09bc3b92359a.
Report an issue: GitHub.