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
- Read the bail! `reason` for the underlying IB rejection and fix the order/contract/account issue.
- Verify IB account permissions (trading permissions, subscriptions) for the instrument.
- Check buying power/margin and order size against account limits.
- 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
- Confirm IB account trading permissions and market-data subscriptions per instrument.
- Check margin/buying power before sizing orders.
- Keep the engine alive to receive rejection events.
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
- Failed to send order submitted event: {e}
- Failed to send order accepted event: {e}
- Order rejected: {reason}
- Order modification rejected: {reason}
- Failed to send SetClient command: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2db668b7710d124f.
Report an issue: GitHub.