nautechsystems/nautilus_trader · error

Failed to send query update_order to database message handle

Error message

Failed to send query update_order to database message handler: {e}

What it means

update_order clones the OrderEventAny into DatabaseQuery::UpdateOrder and sends it over self.tx to the database message handler; a send failure is converted into this anyhow error. Failure implies the handler's receiver was dropped — the persistence task is gone. No order event has been written when this is raised.

Source

Thrown at crates/infrastructure/src/sql/cache.rs:1275

    fn update_strategy(
        &self,
        strategy_id: &StrategyId,
        _state: &AHashMap<String, Bytes>,
    ) -> anyhow::Result<()> {
        anyhow::bail!("update_strategy not implemented for PostgreSQL cache adapter: {strategy_id}")
    }

    fn update_account(&self, account: &AccountAny) -> anyhow::Result<()> {
        let query = DatabaseQuery::AddAccount(account_last_event(account)?, true);
        self.tx.send(query).map_err(|e| {
            anyhow::anyhow!("Failed to send query add_account to database message handler: {e}")
        })
    }

    fn update_order(&self, event: &OrderEventAny) -> anyhow::Result<()> {
        let query = DatabaseQuery::UpdateOrder(event.clone());
        self.tx.send(query).map_err(|e| {
            anyhow::anyhow!("Failed to send query update_order to database message handler: {e}")
        })
    }

    fn update_position(&self, position: &Position) -> anyhow::Result<()> {
        let query = if position.fill_voids.is_empty() {
            DatabaseQuery::UpdatePosition(position_last_event(position)?)
        } else {
            DatabaseQuery::AddPositionSnapshot(PositionSnapshot::from_replay_state(position, None))
        };
        self.tx.send(query).map_err(|e| {
            anyhow::anyhow!("Failed to send query update_position to database message handler: {e}")
        })
    }

    fn snapshot_order_state(&self, order: &OrderAny) -> anyhow::Result<()> {
        let snapshot = OrderSnapshot::from(order.clone());
        self.add_order_snapshot(&snapshot)
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the adapter/handler is live before order event writes
  2. Recreate the adapter instead of writing through a closed channel after shutdown
  3. Find and fix why the handler died (logs)
  4. In live trading, treat this as a persistence outage: buffer or persist events locally until the adapter is restored
Defensive patterns

Strategy: try-catch

Try / catch

try:
    cache.update_order(event)
except Exception as e:
    if "Failed to send query update_order" in str(e):
        logger.error("order event persistence failed: handler down; buffering")
        pending_events.append(event)  # replay after adapter recovery

Prevention

When it happens

Trigger: Calling update_order (or py_update_order) once the handler task has exited via shutdown, abort, or failed initialization.

Common situations: Order events arriving during teardown of the database adapter; handler panic from an earlier failing query; stale cache handles after a restart.

Related errors


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