nautechsystems/nautilus_trader · error · anyhow::Error
Failed to send account state: {e}
Error message
Failed to send account state: {e} What it means
generate_account_state builds an AccountState event and sends it through the shared execution event sender channel; if the channel send fails (receiver dropped or closed), the error is wrapped with anyhow::anyhow! into 'Failed to send account state: {e}'. This means the execution engine can no longer receive account updates, usually because the live execution engine has shut down or the channel was disconnected.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/core.rs:529
info: Option<Params>,
) -> anyhow::Result<()> {
let factory = OrderEventFactory::new(
self.core.trader_id,
self.core.account_id,
self.core.account_type,
self.core.base_currency,
);
let state = factory.generate_account_state(
balances,
margins,
reported,
ts_event,
get_atomic_clock_realtime().get_time_ns(),
info,
);
get_exec_event_sender()
.send(ExecutionEvent::Account(state))
.map_err(|e| anyhow::anyhow!("Failed to send account state: {e}"))
}
fn start(&mut self) -> anyhow::Result<()> {
// Start is handled by connect() for live clients
Ok(())
}
fn stop(&mut self) -> anyhow::Result<()> {
self.begin_task_shutdown();
Ok(())
}
fn submit_order(&self, cmd: SubmitOrder) -> anyhow::Result<()> {
let order = self.core.get_order(&cmd.client_order_id)?;
if let Err(reason) = validate_order(&order) {
let reason = reason.to_string();
Self::send_order_denied(
cmd.order_init.trader_id,View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the execution engine outlives the IB client or stop account subscriptions before tearing down the engine.
- Check shutdown ordering in the trading node: unsubscribe/stop the data and execution clients before dropping the engine and its event channel.
- Inspect logs preceding this error for engine panics or disconnects that closed the event channel unexpectedly.
Example fix
// before
get_exec_event_sender()
.send(ExecutionEvent::Account(state))
.map_err(|e| anyhow::anyhow!("Failed to send account state: {e}"))
// after
match get_exec_event_sender().send(ExecutionEvent::Account(state)) {
Ok(()) => Ok(()),
Err(e) if e.is_disconnected() => {
tracing::debug!("Execution event channel closed; dropping account state update");
Ok(())
}
Err(e) => Err(anyhow::anyhow!("Failed to send account state: {e}")),
} Defensive patterns
Strategy: try-catch
Validate before calling
fn event_channel_alive(sender: &Sender<ExecutionEvent>) -> bool {
!sender.is_closed()
} Try / catch
match get_exec_event_sender().send(ExecutionEvent::Account(state)) {
Err(e) if e.is_disconnected() => tracing::debug!("Engine channel closed during shutdown"),
Err(e) => return Err(anyhow::anyhow!("Failed to send account state: {e}")),
Ok(()) => {}
} Prevention
- Stop account subscriptions before shutting down the execution engine.
- Keep the engine receiver alive as long as live clients may emit events.
- Treat disconnected-channel errors during teardown as benign and log at debug level.
When it happens
Trigger: A IB account summary/balance update arrives and generate_account_state tries send() on the ExecutionEvent channel while the receiving ExecutionEngine has been stopped, dropped, or its receiver disconnected.
Common situations: Shutting down a trading node while account subscription updates are still streaming in; an execution engine panic or disconnect closing the channel; race between client teardown and in-flight account events.
Related errors
- Failed to send order submitted event: {e}
- Failed to send order rejected event: {e}
- Failed to send order accepted event: {e}
- Failed to send order updated event: {e}
- Failed to send order canceled event: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b0beba2bedaf986a.
Report an issue: GitHub.