nautechsystems/nautilus_trader · error · anyhow::Error

Failed to send order canceled event: {e}

Error message

Failed to send order canceled event: {e}

What it means

The adapter received an order-canceled status from IB but could not forward the resulting OrderCanceled event through the exec_sender channel because the receiver was dropped. Like the other send failures in core_updates.rs, it signals that the execution event pipeline is no longer accepting events while IB callbacks continue to arrive.

Source

Thrown at crates/adapters/interactive_brokers/src/execution/core_updates.rs:603

                    strategy_id_map,
                )?;

                let event = OrderCanceled::new(
                    trader_id,
                    strategy_id,
                    instrument_id,
                    client_order_id,
                    UUID4::new(),
                    ts_init,
                    ts_init,
                    false,
                    Some(venue_order_id),
                    Some(account_id),
                    None,
                );
                exec_sender
                    .send(ExecutionEvent::Order(OrderEventAny::Canceled(event)))
                    .map_err(|e| anyhow::anyhow!("Failed to send order canceled event: {e}"))?;
                tracing::debug!("Order {} canceled", client_order_id);
            }
            Some(IbOrderStatus::PendingCancel) => {
                Self::emit_order_pending_cancel(
                    status.order_id,
                    client_order_id,
                    venue_order_id,
                    instrument_id_map,
                    trader_id_map,
                    strategy_id_map,
                    pending_cancel_orders,
                    exec_sender,
                    ts_init,
                    account_id,
                )?;
                tracing::debug!("Order {} pending cancel", client_order_id);
            }
            _ => {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Keep the ExecutionEngine/event receiver alive until the IB adapter is fully disconnected.
  2. Disconnect the IB client and stop order-status handling before dropping the receiver during shutdown.
  3. Treat send failures during intentional shutdown as benign and log them instead of erroring.

Example fix

// before
exec_sender
    .send(ExecutionEvent::Order(OrderEventAny::Canceled(event)))
    .map_err(|e| anyhow::anyhow!("Failed to send order canceled event: {e}"))?;
// after
if let Err(e) = exec_sender.send(ExecutionEvent::Order(OrderEventAny::Canceled(event))) {
    tracing::warn!("Execution channel closed, dropping order canceled event: {e}");
}
tracing::debug!("Order {} canceled", client_order_id);
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: skip event emission if the consumer is gone
if exec_sender.is_closed() {
    tracing::warn!("Execution event channel closed; order canceled event dropped");
    return Ok(());
}

Type guard

fn receiver_alive(sender: &mpsc::Sender<ExecutionEvent>) -> bool {
    !sender.is_closed()
}

Try / catch

if let Err(e) = exec_sender.send(ExecutionEvent::Order(OrderEventAny::Canceled(event))) {
    tracing::warn!("Order canceled event dropped: {e}");
}

Prevention

When it happens

Trigger: handle_order_status matches IbOrderStatus::Cancelled, builds an OrderCanceled event, and calls exec_sender.send(...); the send fails because the channel receiver was dropped or closed before this callback ran.

Common situations: Node/engine stopped or cancelled while IB Gateway still reports cancellations; race between engine shutdown and in-flight order status messages; consumer task terminated by an earlier error.

Related errors


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