getzola/zola · error
result cache lock
Error message
result cache lock
What it means
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.
Source
Thrown at components/templates/src/functions/load_data.rs:317
// source is None only with path_arg (not URL), so path_arg is safely unwrap
return Err(Error::message(format!(
"`load_data`: {} doesn't exist",
self.base_path.join(path_arg.unwrap()).display()
)));
}
(Ok(Some(data_source)), _) => data_source,
};
let file_format = get_output_format_from_args(format_arg, &data_source)?;
let cache_key = data_source.get_cache_key(
&file_format,
method,
&post_body_arg,
&post_content_type,
&headers,
);
let mut cache = self.result_cache.lock().expect("result cache lock");
if let Some(cached_result) = cache.get(&cache_key) {
return Ok(cached_result.clone());
}
let data = match data_source {
DataSource::Path(path) => read_file(&path).map_err(|e| {
Error::message(format!("`load_data`: error reading file {:?}: {}", path, e))
}),
DataSource::Url(url) => {
let response_client = self.client.lock().expect("response client lock");
let req = match method {
Method::Get => response_client
.get(url.as_str())
.headers(add_headers_from_args(headers)?)
.header(header::ACCEPT, file_format.as_accept_header()),
Method::Post => {
let mut resp = response_client
.post(url.as_str())View on GitHub (pinned to 61d3082821)
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
Example fix
// before
let mut cache = self.result_cache.lock().expect("result cache lock");
// after
let mut cache = self
.result_cache
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner()); Defensive patterns
Strategy: try-catch
Try / catch
let mut cache = match self.result_cache.lock() {
Ok(c) => c,
Err(poisoned) => {
log::warn!("result cache poisoned, recovering data");
poisoned.into_inner()
}
}; Prevention
- 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
When it happens
Trigger: 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.
Common situations: Parallel site builds where one worker thread panics on a bad file and all later load_data calls cascade-panic with 'PoisonError'.
Related errors
- Couldn't lock imageproc (set_base_url)
- Couldn't lock imageproc (num_img_ops)
- response client lock
- Couldn't lock imageproc (process_images)
- result cache lock
AI-assisted analysis of getzola/zola@61d3082821 (2026-09-03).
Data as JSON: /api/errors/3c42f5864b5b1061.
Report an issue: GitHub.