{"record":{"id":"a74ae84340f398ff","repo":"getzola/zola","slug":"couldn-t-lock-imageproc-process-images","errorCode":null,"errorMessage":"Couldn't lock imageproc (process_images)","messagePattern":"Couldn't lock imageproc \\(process_images\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"components/site/src/lib.rs","lineNumber":692,"sourceCode":"            copy_directory(\n                &self.static_path,\n                &self.output_path,\n                self.config.hard_link_static,\n                self.config.ignored_static_globset.as_ref(),\n            )?;\n        }\n\n        Ok(())\n    }\n\n    pub fn num_img_ops(&self) -> usize {\n        let imageproc = self.imageproc.lock().expect(\"Couldn't lock imageproc (num_img_ops)\");\n        imageproc.num_img_ops()\n    }\n\n    pub fn process_images(&self) -> Result<()> {\n        let mut imageproc =\n            self.imageproc.lock().expect(\"Couldn't lock imageproc (process_images)\");\n        imageproc.prune()?;\n        imageproc.do_process()\n    }\n\n    /// Deletes the `public` directory if it exists and the `preserve_dotfiles_in_output` option is set to false,\n    /// or if set to true: its contents except for the dotfiles at the root level.\n    pub fn clean(&self) -> Result<()> {\n        clean_site_output_folder(&self.output_path, self.config.preserve_dotfiles_in_output)\n    }\n\n    fn copy_assets(&self, parent: &Path, assets: &[impl AsRef<Path>], dest: &Path) -> Result<()> {\n        for asset in assets {\n            let asset_path = asset.as_ref();\n            copy_file_if_needed(\n                asset_path,\n                &dest.join(\n                    asset_path.strip_prefix(parent).expect(\"Couldn't get filename from page asset\"),\n                ),","sourceCodeStart":674,"sourceCodeEnd":710,"githubUrl":"https://github.com/getzola/zola/blob/61d30828217957120309db657950224edf9707e2/components/site/src/lib.rs#L674-L710","documentation":"Site::process_images locks the shared imageproc Mutex to prune and process pending image operations, panicking with this expect message if the lock is poisoned. This runs during build() (called by build when rebuilding), so a poisoned lock aborts the whole build.","triggerScenarios":"Calling build/process_images after another thread panicked while holding the imageproc lock (e.g. a template function like resize_image panicked mid-operation).","commonSituations":"Live-reload/rebuild servers where a first build panicked in image handling and the subsequent rebuild hits the poisoned mutex.","solutions":["Fix the underlying panic in image processing (the original panic message appears earlier in the log).","Recover with unwrap_or_else(|p| p.into_inner()) if poisoned state is acceptable.","Restart the build process/server after an image-processing panic instead of reusing the poisoned Site.","Add error handling in image operations so workers return Result instead of panicking."],"exampleFix":"// before\nlet mut imageproc = self.imageproc.lock().expect(\"Couldn't lock imageproc (process_images)\");\n// after\nlet mut imageproc = self.imageproc.lock().unwrap_or_else(|p| p.into_inner());","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Detect poisoned-lock panic and retry with a fresh process\nmatch std::panic::catch_unwind(|| site.process_images()) {\n    Ok(res) => res?,\n    Err(_) => { /* rebuild Site / restart worker, then retry once */ }\n}","preventionTips":["Fix the root-cause panic in image processing; it poisons the lock for every later build.","Restart live-reload servers after a failed build.","Keep image operations error-returning instead of panicking under the lock.","Use into_inner() recovery if poisoned imageproc state is still consistent."],"tags":["mutex","poisoned-lock","concurrency","build"],"backgroundTag":"mutex-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"}