{"record":{"id":"f1aef5cc77fff7f8","repo":"nautechsystems/nautilus_trader","slug":"load-custom-data-channel-closed-e","errorCode":null,"errorMessage":"load_custom_data channel closed: {e}","messagePattern":"load_custom_data channel closed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/redis/cache.rs","lineNumber":485,"sourceCode":"    /// test runtimes, plain threads).\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the query fails or the reply channel is closed.\n    pub fn load_custom_data(&self, data_type: &DataType) -> anyhow::Result<Vec<CustomData>> {\n        let con = self.con.clone();\n        let trader_key = self.trader_key.clone();\n        let data_type = data_type.clone();\n        let (tx, rx) = mpsc::channel();\n\n        get_runtime().spawn(async move {\n            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","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/redis/cache.rs#L467-L503","documentation":"Raised by RedisCache::load_custom_data when blocking_recv on the result channel fails, i.e. the spawned worker that ran DatabaseQueries::load_custom_data terminated without sending a result (the oneshot/mpsc receiver reports the channel closed). It surfaces async Redis read failures to the synchronous caller.","triggerScenarios":"Calling load_custom_data (or py_load_custom_data); the spawned query task is dropped, aborted, or panics before tx.send, so blocking_recv(&rx) errors and is wrapped as 'load_custom_data channel closed: {e}'.","commonSituations":"Redis connection error inside the async query, task cancellation during runtime shutdown, a panic in the query path, or runtime teardown racing with the load call.","solutions":["Check the wrapped error and preceding logs (the worker logs 'Failed to send custom data result') for the root Redis error","Verify the Redis server and connection are healthy, then retry the load","Ensure the async runtime is not being shut down while load_custom_data is pending","Confirm the trader key and data type exist; a persistent query failure can also abort the flow"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check connection before loading custom data\nif !cache.check_connection() {\n    anyhow::bail!(\"redis connection down; cannot load custom data\");\n}","typeGuard":null,"tryCatchPattern":"let data = match cache.load_custom_data(trader_key, data_type) {\n    Ok(d) => d,\n    Err(e) if e.to_string().contains(\"channel closed\") => {\n        log::error!(\"load_custom_data worker died: {e:#}; retrying after reconnect\");\n        cache.reconnect()?;\n        cache.load_custom_data(trader_key, data_type)?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Keep the async runtime alive until in-flight loads complete","Watch for the worker's 'Failed to send custom data result' log lines","Validate trader key and data type before calling to avoid repeated query failures"],"tags":["redis","channel-closed","async"],"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"}