{"record":{"id":"3c42f5864b5b1061","repo":"getzola/zola","slug":"result-cache-lock-3c42f5","errorCode":null,"errorMessage":"result cache lock","messagePattern":"result cache lock","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"components/templates/src/functions/load_data.rs","lineNumber":317,"sourceCode":"                // source is None only with path_arg (not URL), so path_arg is safely unwrap\n                return Err(Error::message(format!(\n                    \"`load_data`: {} doesn't exist\",\n                    self.base_path.join(path_arg.unwrap()).display()\n                )));\n            }\n            (Ok(Some(data_source)), _) => data_source,\n        };\n\n        let file_format = get_output_format_from_args(format_arg, &data_source)?;\n        let cache_key = data_source.get_cache_key(\n            &file_format,\n            method,\n            &post_body_arg,\n            &post_content_type,\n            &headers,\n        );\n\n        let mut cache = self.result_cache.lock().expect(\"result cache lock\");\n        if let Some(cached_result) = cache.get(&cache_key) {\n            return Ok(cached_result.clone());\n        }\n\n        let data = match data_source {\n            DataSource::Path(path) => read_file(&path).map_err(|e| {\n                Error::message(format!(\"`load_data`: error reading file {:?}: {}\", path, e))\n            }),\n            DataSource::Url(url) => {\n                let response_client = self.client.lock().expect(\"response client lock\");\n                let req = match method {\n                    Method::Get => response_client\n                        .get(url.as_str())\n                        .headers(add_headers_from_args(headers)?)\n                        .header(header::ACCEPT, file_format.as_accept_header()),\n                    Method::Post => {\n                        let mut resp = response_client\n                            .post(url.as_str())","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/getzola/zola/blob/61d30828217957120309db657950224edf9707e2/components/templates/src/functions/load_data.rs#L299-L335","documentation":"In LoadData::call the result_cache Mutex is locked with .expect(\"result cache lock\"); a poisoned lock (another thread panicked while holding it) makes this panic. Normal concurrent locking with std::sync::Mutex never fails otherwise.","triggerScenarios":"A previous thread panicked while holding the result_cache lock (e.g. during read_file or template evaluation inside call), poisoning the mutex; subsequent load_data template calls then panic.","commonSituations":"Parallel site builds where one worker thread panics on a bad file and all later load_data calls cascade-panic with 'PoisonError'.","solutions":["Fix the underlying panic that poisoned the lock first (check earlier logs)","Replace .expect with .unwrap_or_else(|p| p.into_inner()) to recover cached data despite poisoning","Switch to parking_lot::Mutex which does not poison"],"exampleFix":"// before\nlet mut cache = self.result_cache.lock().expect(\"result cache lock\");\n// after\nlet mut cache = self\n    .result_cache\n    .lock()\n    .unwrap_or_else(|poisoned| poisoned.into_inner());","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let mut cache = match self.result_cache.lock() {\n    Ok(c) => c,\n    Err(poisoned) => {\n        log::warn!(\"result cache poisoned, recovering data\");\n        poisoned.into_inner()\n    }\n};","preventionTips":["Never panic while holding a Mutex; return Result from the critical section instead","Use parking_lot::Mutex for non-poisoning locks","Check logs for the first panic that poisoned the cache before chasing this symptom"],"tags":["rust","mutex","poisoned-lock","panic","concurrency"],"backgroundTag":"mutex-lock-poisoned","analyzedSha":"61d30828217957120309db657950224edf9707e2","analyzedAt":"2026-09-03T14:39:09.727Z","contentChangedAt":"2026-09-03T14:39:09.727Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}