{"record":{"id":"cd124630aa60429f","repo":"nautechsystems/nautilus_trader","slug":"failed-to-send-query-add-signal-to-database-messag","errorCode":null,"errorMessage":"Failed to send query add_signal to database message handler: {e}","messagePattern":"Failed to send query add_signal to database message handler: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/sql/cache.rs","lineNumber":1098,"sourceCode":"                    }\n                }\n                Err(e) => {\n                    log::error!(\"Failed to load bars for instrument {instrument_id}: {e:?}\");\n                    if let Err(e) = tx.send(Vec::new()) {\n                        log::error!(\n                            \"Failed to send empty bars for instrument {instrument_id}: {e:?}\"\n                        );\n                    }\n                }\n            }\n        });\n        Ok(rx.recv()?)\n    }\n\n    fn add_signal(&self, signal: &Signal) -> anyhow::Result<()> {\n        let query = DatabaseQuery::AddSignal(signal.to_owned());\n        self.tx.send(query).map_err(|e| {\n            anyhow::anyhow!(\"Failed to send query add_signal to database message handler: {e}\")\n        })\n    }\n\n    fn load_signals(&self, name: &str) -> anyhow::Result<Vec<Signal>> {\n        let pool = self.pool.clone();\n        let name = name.to_owned();\n        let (tx, rx) = std::sync::mpsc::channel();\n\n        tokio::spawn(async move {\n            let result = DatabaseQueries::load_signals(&pool, &name).await;\n            match result {\n                Ok(signals) => {\n                    if let Err(e) = tx.send(signals) {\n                        log::error!(\"Failed to send signals for '{name}': {e:?}\");\n                    }\n                }\n                Err(e) => {\n                    log::error!(\"Failed to load signals for '{name}': {e:?}\");","sourceCodeStart":1080,"sourceCodeEnd":1116,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/cache.rs#L1080-L1116","documentation":"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.","triggerScenarios":"Calling add_signal (or py_add_signal) once the handler task has exited: adapter stopped, task aborted, or handler failed during initialization.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    cache.add_signal(signal)\nexcept Exception as e:\n    if \"Failed to send query add_signal\" in str(e):\n        logger.error(\"signal persistence failed: handler task gone\")\n        raise","preventionTips":["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"],"tags":["rust","channel","database","postgres"],"backgroundTag":"broken-pipe","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}