nautechsystems/nautilus_trader · error · anyhow::Error
Failed to replay SubscribeUser: {e}
Error message
Failed to replay SubscribeUser: {e} What it means
On reconnect, connect() replays a previously established user-channel subscription by sending HandlerCommand::SubscribeUser to the freshly spawned handler task's command channel. This error means that send failed — the new handler task's receiver was already gone, i.e. the newly started handler exited immediately (spawn failure or instant panic/error), so the user subscription could not be restored on the new session.
Source
Thrown at crates/adapters/polymarket/src/websocket/client.rs:317
WsChannel::Market => {
let topics = self.subscriptions.reset_after_reconnect();
if !topics.is_empty() || self.discovery_subscribed.load(Ordering::Relaxed) {
log::debug!(
"Replaying market subscription state onto new session: assets={}, discovery={}",
topics.len(),
self.discovery_subscribed.load(Ordering::Relaxed),
);
Some((topics, connection_epoch))
} else {
None
}
}
WsChannel::User => {
if self.user_subscribed.load(Ordering::Relaxed) {
log::debug!("Replaying user subscribe onto new session");
cmd_tx
.send(HandlerCommand::SubscribeUser)
.map_err(|e| anyhow::anyhow!("Failed to replay SubscribeUser: {e}"))?;
}
None
}
};
let signal = Arc::clone(&self.signal);
let channel = self.channel;
let credential = self.credential.clone();
let subscriptions = self.subscriptions.clone();
let discovery_subscribed = Arc::clone(&self.discovery_subscribed);
let auth_tracker = self.auth_tracker.clone();
let user_subscribed = self.user_subscribed.load(Ordering::Relaxed);
let subscribe_new_markets = self.subscribe_new_markets;
if let Err(e) = self.task_handle.spawn(async move {
let mut handler = FeedHandler::new(
signal,
channel,View on GitHub (pinned to 18893faf8b)
Solutions
- Retry connect() after a short backoff — a transient spawn/connect failure often succeeds on the next attempt
- Verify auth credentials (API key/secret/passphrase) are still valid, since handler startup failures commonly stem from auth
- Check handler task logs/panic output for the immediate-exit cause
- After a successful connect(), confirm user_subscribed state matches reality and re-issue subscribe_user() if needed
Example fix
// before
client.connect().await?; // replay may fail if handler dies instantly
// after
for attempt in 0..3 {
match client.connect().await {
Ok(()) => break,
Err(e) if attempt < 2 => tokio::time::sleep(Duration::from_millis(250 * (1 << attempt))).await,
Err(e) => return Err(e),
}
} Defensive patterns
Strategy: retry
Validate before calling
// validate auth material before reconnect so the handler does not die at startup
if api_key.is_empty() || api_secret.is_empty() {
return Err(anyhow::anyhow!("credentials required for user channel replay"));
} Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("Failed to replay SubscribeUser") => {
tokio::time::sleep(Duration::from_millis(500)).await;
client.connect().await?; // retry: fresh handler may survive
}
other => other?,
} Prevention
- Use bounded exponential backoff around connect() for reconnects
- Keep API credentials valid/rotated — startup auth failures kill the fresh handler instantly
- Avoid connect() loops that spawn and cancel handlers faster than they initialize
- After reconnect, verify user_subscribed state and re-issue subscribe_user() if needed
When it happens
Trigger: A reconnect where the just-spawned handler task dies before consuming commands — e.g. the WebSocket endpoint refuses the new connection repeatedly, the handler panics during startup, or the task is cancelled right after spawn.
Common situations: Flaky network or gateway outage during reconnect; auth credentials revoked so the handler exits on first auth attempt; calling connect() in a loop that cancels tasks faster than they can run.
Related errors
- Failed to send SubscribeMarket: {e}
- Failed to send UnsubscribeMarket: {e}
- Failed to send SubscribeUser: {e}
- Failed to send SetClient command: {e}
- unsupported Derive public WS channel `{}`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3428fb7871b8e744.
Report an issue: GitHub.