nautechsystems/nautilus_trader · warning
Polymarket RTDS task owner was dropped
Error message
Polymarket RTDS task owner was dropped
What it means
Raised during RTDS shutdown/teardown when the task-slot owner has already been dropped, so retained tasks cannot be finalized. The code clears the reset-live-state flag, notifies reconcilers, then bails because there is no task owner left to shut down. It signals a double shutdown or shutdown of an already-torn-down feed.
Source
Thrown at crates/adapters/polymarket/src/rtds.rs:646
}
self.inner.reconcile_pending.store(true, Ordering::Release);
self.ensure_reconcile_worker();
self.inner.reconcile_notify.notify_one();
}
pub(crate) async fn disconnect(&self) -> anyhow::Result<()> {
self.begin_shutdown();
let _guard = self.inner.wire_mutex.lock().await;
self.inner.reconcile_pending.store(false, Ordering::Release);
self.inner
.reset_live_state_pending
.store(false, Ordering::Release);
self.inner.reconcile_notify.notify_waiters();
let Some(tasks) = self.task_slots() else {
anyhow::bail!("Polymarket RTDS task owner was dropped");
};
let mut ws = RtdsWebSocketGuard::take(&self.inner.ws_client);
if let Some(client) = ws.ws.as_ref() {
client.disconnect().await;
}
if let Some(control) = &self.inner.socket_control {
control.deregister();
}
self.inner.live_subscriptions.lock().clear();
drop(_guard);
let mut message_slot = tasks.message.lock().await;
if let Some(outcome) = finish_task(
&mut message_slot,
Duration::from_secs(2),View on GitHub (pinned to 18893faf8b)
Solutions
- Make shutdown idempotent: check whether task slots still exist before calling close.
- Serialize shutdown calls (single closer task, JoinHandle, or a OnceLock-style flag).
- Treat this error as 'already shut down' and ignore it in close paths.
- Ensure exactly one component owns and closes the feed.
Example fix
// before
feed.close().await?; // second call bails
feed.close().await?;
// after
if !feed.is_closed() {
feed.close().await?;
} Defensive patterns
Strategy: try-catch
Validate before calling
if feed.is_closed() {
return Ok(()); // already shut down
} Type guard
fn needs_shutdown(feed: &PolymarketRtdsFeed) -> bool {
!feed.is_closed() && feed.task_slots().is_some()
} Try / catch
if let Err(e) = feed.close().await {
if e.to_string().contains("task owner was dropped") {
log::debug!("already shut down");
} else {
return Err(e);
}
} Prevention
- Make shutdown idempotent and call it from exactly one place.
- Use a OnceLock/flag so close cannot run twice.
- Rely on Drop for teardown rather than mixing explicit and implicit close.
- Ignore owner-dropped errors in close paths — they mean the work is done.
When it happens
Trigger: Calling close/shutdown on the Polymarket RTDS feed when the RtdsTaskSlots owner was already dropped — a second close call, or close racing a completed teardown from another task.
Common situations: Calling disconnect/shutdown twice (e.g. from both a Drop impl and an explicit shutdown path); engine teardown invoking close on a feed whose supervisor already exited.
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
- Polymarket data shutdown failed: {}
- RTDS task owner was dropped
- RTDS connection was canceled by shutdown
- Polymarket market pool shutdown failed: {}
- {errors.join("; ")}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ae4f7e701f5a6613.
Report an issue: GitHub.