nautechsystems/nautilus_trader · error

Failed to send query update_position to database message han

Error message

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

What it means

update_position builds either DatabaseQuery::UpdatePosition (last position event) or DatabaseQuery::AddPositionSnapshot (when fill_voids exist) and sends it over self.tx to the database message handler; send failure becomes this error. The only failure mode is a dropped receiver — the background persistence task is not running. Position state was not persisted when this fires.

Source

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

            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)
    }

    fn snapshot_position_state(
        &self,
        position: &Position,
        ts_snapshot: UnixNanos,
        unrealized_pnl: Option<Money>,
    ) -> anyhow::Result<()> {
        let mut snapshot = if position.fill_voids.is_empty() {
            PositionSnapshot::from(position, unrealized_pnl)
        } else {
            PositionSnapshot::from_replay_state(position, unrealized_pnl)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the database adapter and handler task are running before position updates
  2. Recreate the adapter after any shutdown instead of reusing closed instances
  3. Fix the handler's exit root cause found in logs
  4. Guard position persistence: losing position updates corrupts recovery state, so surface this error prominently
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(e) = cache.update_position(&position) {
    tracing::error!("position persistence failed: {e:#}");
    return Err(e.into());  // position state loss corrupts recovery
}

Prevention

When it happens

Trigger: Calling update_position after the handler task terminated: adapter shutdown, task abort, or handler dying at startup.

Common situations: Position updates during node shutdown ordering issues; handler crashed earlier leaving the channel closed; adapter recreated elsewhere while old instance still referenced.

Related errors


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