nautechsystems/nautilus_trader · error · anyhow::Error

Failed to send order event: {e}

Error message

Failed to send order event: {e}

What it means

try_send_order_event obtained a valid sender but the underlying channel send failed, meaning the receiving end of the execution event channel has been dropped/closed. The wrapped channel error `e` is included in the message. This typically indicates the consumer (execution engine) has shut down or been torn down while a producer still tries to emit.

Source

Thrown at crates/live/src/execution/emitter.rs:444

    pub fn send_order_event(&self, event: OrderEventAny) {
        if let Err(e) = self.try_send_order_event(event) {
            log::warn!("{e}");
        }
    }

    /// Emits an order event and returns any channel error to the caller.
    ///
    /// # Errors
    ///
    /// Returns an error if the sender is uninitialized or its receiver is closed.
    pub fn try_send_order_event(&self, event: OrderEventAny) -> anyhow::Result<()> {
        let sender = self.sender.load();
        let sender = sender
            .as_ref()
            .ok_or_else(|| anyhow::anyhow!("Cannot send order event: sender not initialized"))?;
        sender
            .send(ExecutionEvent::Order(event))
            .map_err(|e| anyhow::anyhow!("Failed to send order event: {e}"))
    }

    /// Emits a batch of order submitted events as a single channel message.
    pub fn send_order_submitted_batch(&self, batch: OrderSubmittedBatch) {
        let sender = self.sender.load();
        if let Some(sender) = sender.as_ref() {
            if let Err(e) = sender.send(ExecutionEvent::OrderSubmittedBatch(batch)) {
                log::warn!("Failed to send order submitted batch: {e}");
            }
        } else {
            log::warn!("Cannot send order submitted batch: sender not initialized");
        }
    }

    /// Emits a batch of order accepted events as a single channel message.
    pub fn send_order_accepted_batch(&self, batch: OrderAcceptedBatch) {
        let sender = self.sender.load();
        if let Some(sender) = sender.as_ref() {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check whether the execution engine/node was stopped before this call; stop emitting after shutdown begins.
  2. Reorder lifecycle so recovery/reconnect emissions happen only while the receiver is alive.
  3. Log and tolerate this error during shutdown races instead of treating it as fatal.
  4. Inspect the included channel error `e` to confirm the receiver-closed cause.

Example fix

// before
emitter.try_send_order_event(event)?;
// after
if let Err(e) = emitter.try_send_order_event(event) {
    log::warn!("order event not delivered (engine likely stopped): {e}");
}
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(e) = emitter.try_send_order_event(event) { log::warn!("order event undelivered (receiver closed?): {e}"); }

Prevention

When it happens

Trigger: Calling try_send_order_event after the receiver side of the channel was dropped — e.g. during node shutdown, after the execution engine was stopped, or when the event stream consumer panicked and its task exited.

Common situations: Emitting order events during teardown; reconnect handlers firing while the engine is being restarted; a stuck/crashed consuming task causing the channel to be closed (in unbounded/bounded channel semantics where send fails when receiver is gone).

Related errors


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