{"record":{"id":"78dce5ccd35643fb","repo":"nautechsystems/nautilus_trader","slug":"failed-to-send-to-channel-e","errorCode":null,"errorMessage":"Failed to send to channel: {e}","messagePattern":"Failed to send to channel: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/infrastructure/src/redis/cache.rs","lineNumber":497,"sourceCode":"            let result = DatabaseQueries::load_custom_data(&con, &trader_key, &data_type).await;\n            if let Err(e) = tx.send(result) {\n                log::error!(\"Failed to send custom data result for '{data_type}': {e:?}\");\n            }\n        });\n\n        blocking_recv(&rx).map_err(|e| anyhow::anyhow!(\"load_custom_data channel closed: {e}\"))?\n    }\n\n    /// Sends an insert command for `key` with optional `payload` to Redis via the background task.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the command cannot be sent to the background task channel.\n    pub fn insert(&self, key: String, payload: Option<Vec<Bytes>>) -> anyhow::Result<()> {\n        let op = DatabaseCommand::new(DatabaseOperation::Insert, key, payload);\n        match self.tx.send(op) {\n            Ok(()) => Ok(()),\n            Err(e) => anyhow::bail!(\"{FAILED_TX_CHANNEL}: {e}\"),\n        }\n    }\n\n    /// Stores custom data in Redis (key format: `custom:<ts_init_020>:<uuid>`, value: full JSON).\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if serialization fails or the insert command cannot be sent.\n    pub fn add_custom_data(&self, data: &CustomData) -> anyhow::Result<()> {\n        let json_bytes = serde_json::to_vec(data)\n            .map_err(|e| anyhow::anyhow!(\"CustomData serialization failed: {e}\"))?;\n        let ts_init = data.ts_init().as_u64();\n        let key = format!(\n            \"{CUSTOM}{REDIS_DELIMITER}{:020}{REDIS_DELIMITER}{}\",\n            ts_init,\n            UUID4::new()\n        );\n        self.insert(key, Some(vec![Bytes::from(json_bytes)]))","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/redis/cache.rs#L479-L515","documentation":"RedisCache::insert enqueues a DatabaseCommand::Insert onto an mpsc channel serviced by a background Redis task. If that task has already terminated (receiver dropped), send fails and the error is surfaced as \"Failed to send to channel: <send error>\". The write never reaches Redis.","triggerScenarios":"Calling cache.insert(...) (directly or via py_insert / add_custom_data) after the background cache task has shut down or the cache was constructed without a live receiver task.","commonSituations":"Live/trading node shutting down while a callback still tries to persist data; background task crashed earlier; cache object kept alive past its owning runtime's lifetime.","solutions":["Verify the background Redis cache task is running and healthy before insert; restart/reinitialize it if it stopped.","Check logs for a prior panic or error that killed the background task.","Guard shutdown ordering so all cache writes complete before the task/channel is dropped."],"exampleFix":"// before\nnode.stop();\ncache.insert(key, payload)?; // send fails: receiver dropped\n// after\ncache.insert(key, payload)?;\nnode.stop();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match cache.insert(key, payload) {\n    Ok(()) => {}\n    Err(e) if e.to_string().starts_with(\"Failed to send to channel\") => {\n        log::error!(\"redis cache background task is down: {e}\");\n        // reinitialize cache or buffer the write for retry\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Start the background Redis task before any component uses the cache.","Monitor task liveness and reconnect/respawn on failure.","Enforce shutdown ordering: flush cache writes before stopping the task.","Avoid holding cache handles beyond the runtime lifetime (e.g. in Python wrappers)."],"tags":["redis","cache","channel","send-failed","rust"],"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"}