nautechsystems/nautilus_trader · error
Failed to send query add_order_snapshot to database message
Error message
Failed to send query add_order_snapshot to database message handler: {e} What it means
Thrown by `add_position_snapshot` when the `DatabaseQuery::AddPositionSnapshot` message cannot be sent to the database message-handler task because the receiving end of the channel was dropped. The snapshot is not persisted. Despite the message text, this is the position-snapshot write path.
Source
Thrown at crates/infrastructure/src/sql/cache.rs:975
self.tx.send(query).map_err(|e| {
anyhow::anyhow!(
"Failed to send query add_order_snapshot to database message handler: {e}"
)
})
}
fn add_position(&self, position: &Position) -> anyhow::Result<()> {
let event = position_last_event(position)?;
let query = DatabaseQuery::AddPosition(position.id, event);
self.tx.send(query).map_err(|e| {
anyhow::anyhow!("Failed to send query add_position to database message handler: {e}")
})
}
fn add_position_snapshot(&self, snapshot: &PositionSnapshot) -> anyhow::Result<()> {
let query = DatabaseQuery::AddPositionSnapshot(snapshot.to_owned());
self.tx.send(query).map_err(|e| {
anyhow::anyhow!(
"Failed to send query add_position_snapshot to database message handler: {e}"
)
})
}
fn add_order_book(&self, _order_book: &OrderBook) -> anyhow::Result<()> {
todo!()
}
fn add_quote(&self, quote: &QuoteTick) -> anyhow::Result<()> {
let query = DatabaseQuery::AddQuote(quote.to_owned());
self.tx.send(query).map_err(|e| {
anyhow::anyhow!("Failed to send query add_quote to database message handler: {e}")
})
}
fn load_quotes(&self, instrument_id: &InstrumentId) -> anyhow::Result<Vec<QuoteTick>> {
let pool = self.pool.clone();View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the adapter is running before taking position snapshots.
- Check for panics in the message-handler task.
- Reconnect/recreate the adapter and re-issue the snapshot.
- Sequence shutdown so snapshots are flushed before the writer stops.
Example fix
// before
self.tx.send(query).map_err(|e| anyhow::anyhow!("Failed to send query add_position_snapshot to database message handler: {e}"))?;
// after
if self.tx.is_closed() {
return Err(anyhow::anyhow!("Cannot persist position snapshot: database message handler is stopped"));
}
self.tx.send(query).map_err(|e| anyhow::anyhow!("Failed to send query add_position_snapshot to database message handler: {e}"))?; Defensive patterns
Strategy: try-catch
Validate before calling
if not cache_db_adapter.is_running:
raise RuntimeError("Cannot snapshot position state: adapter not running") Try / catch
try:
cache.add_position_snapshot(snapshot)
except RuntimeError as e:
logger.error("Position snapshot persistence failed: %s", e) Prevention
- Snapshot positions while the adapter is running
- Sequence shutdown so the writer stops last
- Monitor writer task health
- Retry the snapshot after reconnecting the adapter
When it happens
Trigger: Calling `add_position_snapshot` (via `py_add_position_snapshot` or `snapshot_position_state`) when the writer task has exited or panicked.
Common situations: Snapshotting position state during shutdown; dead writer task from an earlier handler crash.
Related errors
- Failed to send query add_position to database message handle
- Failed to send query to database message handler: {e}
- Failed to query add_currency to database message handler: {e
- Failed to send query add_instrument to database message hand
- Failed to send query add_instrument_close to database messag
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/96f3a281a950fadb.
Report an issue: GitHub.