nautechsystems/nautilus_trader · error · anyhow::Error

Failed to terminate Polymarket execution tasks: {e}

Error message

Failed to terminate Polymarket execution tasks: {e}

What it means

This error wraps a failure from `await_pending_tasks` when draining all in-flight Polymarket execution tasks during adapter teardown. It is raised by `teardown_partial_connect` and `connect_client` to convert the underlying task-group shutdown error into a contextual anyhow error, so the original cause is preserved in the `{e}` chain. It means graceful termination of execution tasks did not complete within the allowed timeouts.

Source

Thrown at crates/adapters/polymarket/src/execution/lifecycle.rs:217

                self.emitter.emit_order_modify_rejected(
                    &order,
                    Some(venue_order_id),
                    "Polymarket modification was interrupted during shutdown",
                    ts_event,
                );

                if let Some(cancel_ts) = cancel_ts
                    && !self.fill_tracker.is_fully_filled(&venue_order_id)
                {
                    self.emitter
                        .emit_order_canceled(&order, Some(venue_order_id), cancel_ts);
                }
            }
        }

        result
            .map_err(|e| anyhow::anyhow!("Failed to terminate Polymarket execution tasks: {e}"))?;
        Ok(())
    }

    pub(super) async fn await_session_tasks(&self) -> anyhow::Result<()> {
        self.session_tasks.begin_shutdown();
        self.session_tasks
            .finish_shutdown(TASK_SESSION_GRACEFUL_SHUTDOWN_TIMEOUT, TASK_ABORT_TIMEOUT)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to terminate Polymarket session tasks: {e}"))?;
        Ok(())
    }

    pub(super) async fn refresh_account_state(&self) -> anyhow::Result<()> {
        fetch_and_emit_account_state(
            &self.http_client,
            &self.emitter,
            self.clock,
            self.config.signature_type,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the chained source error (`e.source()` / anyhow chain) for the real cause of task termination failure
  2. Ensure the HTTP client has adequate timeouts so pending tasks cannot hang indefinitely
  3. Avoid tearing down while tasks are mid-flight; wait for order submissions to complete or cancel them first
  4. Check that no spawned task blocks on a channel that nobody drains
  5. Retry connect_client after the hung task has been aborted by the abort timeout

Example fix

// before: teardown aborts mid-flight tasks
adapter.teardown_partial_connect().await?;
// after: drain outstanding submits before teardown
adapter.wait_for_pending_submits().await;
adapter.teardown_partial_connect().await?;
Defensive patterns

Strategy: try-catch

Validate before calling

// check adapter state before teardown/reconnect
if adapter.has_inflight_submits() {
    adapter.wait_for_pending_submits().await;
}

Try / catch

match adapter.teardown_partial_connect().await {
    Err(e) => { tracing::error!("teardown failed: {e:#}"); /* inspect full anyhow chain */ }
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling teardown_partial_connect or connect_client while pending execution tasks (order submits, cancels) fail to finish or abort within TASK_PENDING_GRACEFUL_SHUTDOWN_TIMEOUT/TASK_ABORT_TIMEOUT; a spawned task hangs on I/O or a channel send with no receiver.

Common situations: Network outage during reconnect while orders are in flight; a hung HTTP call to the Polymarket CLOB preventing task completion; shutting down the adapter while a submit task is blocked; reconnect logic in connect_client racing slow tasks.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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