nautechsystems/nautilus_trader · error
Failed to send query add_quote to database message handler:
Error message
Failed to send query add_quote to database message handler: {e} What it means
The PostgreSQL cache adapter writes are asynchronous: add_quote wraps the QuoteTick in a DatabaseQuery::AddQuote and sends it over an mpsc channel (self.tx) to a background database message handler task. This error is raised when that send fails, which only happens if the receiver half held by the handler task has been dropped — i.e. the background writer task has shut down or was never started. The tick itself is fine; the failure is in the cache's internal messaging plumbing.
Source
Thrown at crates/infrastructure/src/sql/cache.rs:988
}
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();
let instrument_id = instrument_id.to_owned();
let (tx, rx) = std::sync::mpsc::channel();
tokio::spawn(async move {
let result = DatabaseQueries::load_quotes(&pool, &instrument_id).await;
match result {
Ok(quotes) => {
if let Err(e) = tx.send(quotes) {
log::error!("Failed to send quotes for instrument {instrument_id}: {e:?}");
}
}
Err(e) => {
log::error!("Failed to load quotes for instrument {instrument_id}: {e:?}");View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the PostgreSQL cache adapter is fully started and its background handler task is alive before writing quotes
- Recreate or restart the cache/database adapter if it was shut down, instead of reusing the old instance
- Check handler task logs for a panic or early exit (e.g. failed pool connection) and fix the underlying startup cause
- If writes are optional, catch the anyhow error from add_quote and degrade gracefully rather than crashing the strategy
Example fix
// before: writing through a stale adapter after shutdown
cache.add_quote("e)?;
// after: rebuild the adapter when the handler channel is closed
if let Err(e) = cache.add_quote("e) {
if e.to_string().contains("Failed to send query add_quote") {
cache = CacheDatabaseAdapter::new(config)?; // restart handler task
cache.add_quote("e)?;
} else { return Err(e); }
} Defensive patterns
Strategy: try-catch
Try / catch
// Python
try:
cache.add_quote(quote)
except Exception as e:
if "Failed to send query add_quote" in str(e):
logger.error("DB cache handler down; reinitializing adapter")
cache = rebuild_cache_adapter()
else:
raise
// Rust
if let Err(e) = cache.add_quote("e) {
tracing::error!("quote persistence failed: {e:#}");
} Prevention
- Keep the database adapter alive for the entire lifetime of writers
- Establish a single ownership/shutdown order: stop writers, then drop the cache
- Monitor handler task health; restart the adapter if the task exits
- Test shutdown paths so writes never race adapter teardown
When it happens
Trigger: Calling add_quote (directly from Rust or via py_add_quote from Python) after the database message handler task has exited, e.g. the connection pool/task was aborted, the cache was shut down, or the handler task panicked on startup.
Common situations: Closing or dropping the cache/database adapter while a live strategy or script still writes quotes; a startup failure of the message handler (bad DB config) leaving the receiver dropped; holding a stale cache instance after disconnect during a long-running backtest/live session.
Related errors
- Failed to send query add_trade 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/b861b5e4f2c9848e.
Report an issue: GitHub.