nautechsystems/nautilus_trader · error · anyhow::Error

Failed to send order rejected event: {e}

Error message

Failed to send order rejected event: {e}

What it means

In handle_order_submit_failure, when the IB client submit fails with a condition that maps to a terminal rejection, the adapter emits an OrderRejected event via exec_sender. This error wraps a failure of that channel send; the adapter then bail!s with the rejection `reason`. Downstream will neither get the Rejected event nor a clean error about the original IB rejection unless the channel is fixed.

Source

Thrown at crates/adapters/interactive_brokers/src/execution/core_orders.rs:615

                );

                let reason = format!("{failure_prefix}: {reason}");
                let event = OrderRejected::new(
                    context.trader_id,
                    context.strategy_id,
                    context.instrument_id,
                    context.client_order_id,
                    account_id,
                    Ustr::from(&reason),
                    UUID4::new(),
                    ts_event,
                    clock.get_time_ns(),
                    false,
                    false,
                );
                exec_sender
                    .send(ExecutionEvent::Order(OrderEventAny::Rejected(event)))
                    .map_err(|e| anyhow::anyhow!("Failed to send order rejected event: {e}"))?;
                anyhow::bail!(reason);
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use nautilus_model::identifiers::Symbol;

    use super::*;

    fn modify_trigger_cmd() -> ModifyOrder {
        ModifyOrder::new(
            TraderId::from("TRADER-001"),
            Some(ClientId::from("CLIENT-001")),
            StrategyId::from("S-001"),
            InstrumentId::new(Symbol::from("AAPL"), Venue::from("NASDAQ")),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the bail! `reason` for the underlying IB rejection and fix the order/contract/account issue.
  2. Verify IB account permissions (trading permissions, subscriptions) for the instrument.
  3. Check buying power/margin and order size against account limits.
  4. Ensure the exec event channel/receiver is alive; restart the node if the channel was dropped.
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check account permissions and buying power for the contract
ensure!(account.allows_trading(&instrument_id), "no trading permission for {}", instrument_id);

Try / catch

if let Err(e) = exec_client.submit_order(cmd).await {
    if e.to_string().contains("Failed to send order rejected event") {
        // both the IB rejection and the event channel failed; halt and reconcile
    }
}

Prevention

When it happens

Trigger: client.submit_order returning an error classified as a hard rejection (e.g. invalid contract, insufficient permissions/funds, malformed order) while the exec event channel send fails (receiver dropped/closed).

Common situations: Submitting orders for contracts the IB account cannot trade (no market-data/subscriptions permissions); exceeding account buying power; engine shutdown racing a failed submission.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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