nautechsystems/nautilus_trader · error
Failed to send query add_signal to database message handler:
Error message
Failed to send query add_signal to database message handler: {e} What it means
add_signal sends DatabaseQuery::AddSignal through the cache's mpsc channel to the database message handler and converts a send failure into this anyhow error. A failed send means the handler's receiver was dropped — the background task that persists signals is no longer running. The signal value is unaffected; delivery is impossible.
Source
Thrown at crates/infrastructure/src/sql/cache.rs:1098
}
}
Err(e) => {
log::error!("Failed to load bars for instrument {instrument_id}: {e:?}");
if let Err(e) = tx.send(Vec::new()) {
log::error!(
"Failed to send empty bars for instrument {instrument_id}: {e:?}"
);
}
}
}
});
Ok(rx.recv()?)
}
fn add_signal(&self, signal: &Signal) -> anyhow::Result<()> {
let query = DatabaseQuery::AddSignal(signal.to_owned());
self.tx.send(query).map_err(|e| {
anyhow::anyhow!("Failed to send query add_signal to database message handler: {e}")
})
}
fn load_signals(&self, name: &str) -> anyhow::Result<Vec<Signal>> {
let pool = self.pool.clone();
let name = name.to_owned();
let (tx, rx) = std::sync::mpsc::channel();
tokio::spawn(async move {
let result = DatabaseQueries::load_signals(&pool, &name).await;
match result {
Ok(signals) => {
if let Err(e) = tx.send(signals) {
log::error!("Failed to send signals for '{name}': {e:?}");
}
}
Err(e) => {
log::error!("Failed to load signals for '{name}': {e:?}");View on GitHub (pinned to 18893faf8b)
Solutions
- Check the adapter/handler task is running before publishing signals
- Rebuild the cache adapter if it was shut down instead of reusing it
- Diagnose the handler's exit cause (panic, DB failure) from logs
- Catch the error if signal persistence is optional for the run
Defensive patterns
Strategy: try-catch
Try / catch
try:
cache.add_signal(signal)
except Exception as e:
if "Failed to send query add_signal" in str(e):
logger.error("signal persistence failed: handler task gone")
raise Prevention
- Publish signals only while the node's database adapter is active
- Join/await handler task completion during shutdown before final writes
- Add liveness checks around long-running scripts using the cache
- Keep handler task panics from propagating silently
When it happens
Trigger: Calling add_signal (or py_add_signal) once the handler task has exited: adapter stopped, task aborted, or handler failed during initialization.
Common situations: Signal publication near the end of a run after the database adapter was shut down; a handler crash from an earlier query leaving the channel closed; scripts reusing a cache built in a finished async context.
Related errors
- Failed to send query add_quote to database message handler:
- 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 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/cd124630aa60429f.
Report an issue: GitHub.