nautechsystems/nautilus_trader · error · anyhow::Error

WS submit order failed: {e}

Error message

WS submit order failed: {e}

What it means

When use_ws_trading is active, orders are placed over the Binance Spot WebSocket API via place_order_with_id. If that call fails, the pending request id is removed from the dispatch state, a warning about awaiting reconciliation is logged, and the spawned task bails with this error. The order stays SUBMITTED locally and its true venue state must be resolved by reconciliation.

Source

Thrown at crates/adapters/binance/src/spot/execution.rs:367

            dispatch_state.pending_requests.insert(
                request_id.clone(),
                PendingRequest {
                    client_order_id,
                    venue_order_id: None,
                    operation: PendingOperation::Place,
                },
            );

            self.spawn_task("submit_order_ws", async move {
                if let Err(e) = ws_client
                    .place_order_with_id(request_id.clone(), params)
                    .await
                {
                    dispatch_state.pending_requests.remove(&request_id);
                    log::warn!(
                        "WS submit request failed for {client_order_id}, awaiting reconciliation: {e}"
                    );
                    anyhow::bail!("WS submit order failed: {e}");
                }
                Ok(())
            });
        } else {
            let http_client = self.http_client.clone();
            let dispatch_state = self.dispatch_state.clone();
            log::debug!("WS trading not active, falling back to HTTP for submit_order");

            self.spawn_task("submit_order_http", async move {
                let result = http_client
                    .submit_order(
                        account_id,
                        instrument_id,
                        client_order_id,
                        order_side,
                        order_type,
                        quantity,
                        time_in_force,

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Rely on the adapter's reconciliation path to resolve the order's venue state before deciding to resubmit
  2. Retry the submission after a backoff once the session is confirmed healthy and the order is confirmed absent on the venue
  3. Set use_ws_trading=false so submission uses the HTTP REST path (the adapter automatically falls back when the WS transport is inactive)

Example fix

# before
config = BinanceExecClientConfig(use_ws_trading=True)  # WS submit fails intermittently

# after: route orders over REST, user data still streamed
config = BinanceExecClientConfig(use_ws_trading=False)
Defensive patterns

Strategy: retry

Validate before calling

# defensive: only submit when the WS trading transport is healthy or expect HTTP fallback
if not self._engine.client_is_connected():
    raise RuntimeError("venue not connected; refusing to submit")

Try / catch

// in a supervision loop around the execution client:
// on 'WS submit order failed':
//   1. run generate_order_status_reports (reconciliation) for the client_order_id
//   2. if absent on venue -> resubmit after backoff
//   3. if present        -> adopt the venue state and continue
// order remains SUBMITTED locally until reconciled; do not blind-resubmit

Prevention

When it happens

Trigger: The WS place-order request fails inside the spawned 'submit_order_ws' task: session/logon errors, WS rate limits, transient disconnects, or parameter rejections from the venue while the transport was still considered active.

Common situations: Flaky networks between the host and the Binance WS trading endpoint; expired sessions after idle periods; intermittent rate limiting during bursts of submissions; live trading where order state becomes uncertain.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/a544c3a151cea9d6. Report an issue: GitHub.