nautechsystems/nautilus_trader · error
Failed to send query add_trade to database message handler:
Error message
Failed to send query add_trade to database message handler: {e} What it means
add_trade sends a DatabaseQuery::AddTrade over the cache's internal mpsc channel to the database message handler task; the error is produced by map_err when channel send fails. A send fails only when the receiver has been dropped, meaning the background handler is no longer running. The trade data itself is not validated here — the failure is purely internal plumbing.
Source
Thrown at crates/infrastructure/src/sql/cache.rs:1021
}
}
Err(e) => {
log::error!("Failed to load quotes for instrument {instrument_id}: {e:?}");
if let Err(e) = tx.send(Vec::new()) {
log::error!(
"Failed to send empty quotes for instrument {instrument_id}: {e:?}"
);
}
}
}
});
Ok(rx.recv()?)
}
fn add_trade(&self, trade: &TradeTick) -> anyhow::Result<()> {
let query = DatabaseQuery::AddTrade(trade.to_owned());
self.tx.send(query).map_err(|e| {
anyhow::anyhow!("Failed to send query add_trade to database message handler: {e}")
})
}
fn load_trades(&self, instrument_id: &InstrumentId) -> anyhow::Result<Vec<TradeTick>> {
let pool = self.pool.clone();
let instrument_id = instrument_id.to_owned();
let (tx, rx) = std::sync::mpsc::channel();
tokio::spawn(async move {
let result = DatabaseQueries::load_trades(&pool, &instrument_id).await;
match result {
Ok(trades) => {
if let Err(e) = tx.send(trades) {
log::error!("Failed to send trades for instrument {instrument_id}: {e:?}");
}
}
Err(e) => {
log::error!("Failed to load trades for instrument {instrument_id}: {e:?}");View on GitHub (pinned to 18893faf8b)
Solutions
- Confirm the database message handler task is running before calling add_trade
- Restart/recreate the cache adapter after any shutdown; do not write through stale handles
- Inspect handler logs for the reason the receiver was dropped (panic, pool failure) and fix it
- Wrap add_trade calls in error handling if trade persistence is non-critical
Defensive patterns
Strategy: try-catch
Try / catch
try:
cache.add_trade(trade)
except Exception as e:
if "Failed to send query add_trade" in str(e):
logger.error("DB cache handler unavailable")
raise PersistenceError from e Prevention
- Do not reuse cache adapter instances across shutdown/restart cycles
- Log and alert on handler task termination
- Verify adapter startup succeeded before enabling trade writes
- Keep DB config valid so the handler never dies at init
When it happens
Trigger: Calling add_trade (or py_add_trade from Python) when the handler task backing the cache has terminated: adapter shut down, task aborted, or handler exited due to an earlier fatal DB error.
Common situations: A live node tears down its database adapter while a strategy callback still records trades; a handler panic from a previous failed write; using a cache instance obtained before reconnection.
Related errors
- Failed to send query add_quote to database message handler:
- Failed to send query add_bar to database message handler: {e
- Failed to send query add_signal to database message handler:
- Failed to send query index_order_position to database messag
- Failed to send query index_order_clients to database message
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5790b551d2a92efa.
Report an issue: GitHub.