getzola/zola · error
result cache lock
Error message
result cache lock
What it means
The get_url template function caches file hashes in a shared result_cache Mutex. This expect panics when the cache mutex is poisoned — another thread panicked while holding the lock — so subsequent get_url calls in any template render abort with 'result cache lock'.
Source
Thrown at components/templates/src/functions/files.rs:155
}
let path_with_lang = segments.join("/");
let mut permalink = self.config.make_permalink(&path_with_lang);
if !trailing_slash && permalink.ends_with('/') {
permalink.pop(); // Removes the slash
}
if cachebust {
match search_for_file(
&self.base_path,
&path_with_lang,
&self.config.theme,
&self.output_path,
)
.map_err(|e| Error::message(format!("`get_url`: {}", e)))?
.and_then(|(file_path, unified_path)| {
let mut cache = self.result_cache.lock().expect("result cache lock");
if let Some(hash) = cache.get(&unified_path) {
return Some(hash.clone());
}
let mut f = fs::File::open(file_path).ok()?;
let mut contents = Vec::new();
f.read_to_end(&mut contents).ok()?;
let hash = compute_hash::<Sha256>(&contents, false);
cache.insert(unified_path, hash.clone());
Some(hash)
}) {
Some(hash) => {
let short_hash = &hash[..20]; // 2^-80 chance of false positive
permalink = format!("{permalink}?h={short_hash}");
}
None => {
return Err(Error::message(format!(
"`get_url`: Could not find or open file {}",
path_with_langView on GitHub (pinned to 61d3082821)
Solutions
- Fix the original panic inside get_url's cache/hash code; it appears earlier in the log.
- Replace expect with unwrap_or_else(|p| p.into_inner()) to survive poisoning (the cache is a plain HashMap).
- Restart the rendering server after a panic instead of reusing the poisoned state.
- Guard the cache body so hash computation returns Result instead of panicking.
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(|p| p.into_inner()); Defensive patterns
Strategy: try-catch
Try / catch
let mut cache = match self.result_cache.lock() {
Ok(g) => g,
Err(poisoned) => poisoned.into_inner(), // cache is recoverable state
}; Prevention
- Fix panics inside get_url's file-reading path first — they poison the shared cache.
- Restart the template server after a panic rather than continuing.
- Return Result from cache computations instead of panicking under the lock.
- Use into_inner() recovery for caches, whose state is always rebuildable.
When it happens
Trigger: Rendering a template that calls get_url after a panic occurred while another thread held result_cache (e.g. an earlier get_url panicked computing a hash).
Common situations: Multithreaded template rendering (server/live-reload) where one request panics in get_url and later requests hit the poisoned mutex.
Related errors
- Couldn't lock imageproc (set_base_url)
- Couldn't lock imageproc (num_img_ops)
- Couldn't lock imageproc (process_images)
- result cache lock
- result cache lock
AI-assisted analysis of getzola/zola@61d3082821 (2026-09-03).
Data as JSON: /api/errors/6dca8b96cab68fbf.
Report an issue: GitHub.