getzola/zola · error
response client lock
Error message
response client lock
What it means
When load_data fetches a URL, the shared reqwest client behind a Mutex is locked with .expect("response client lock"). If the mutex was poisoned by a panic in another thread while performing a request, this call panics with a PoisonError message.
Source
Thrown at components/templates/src/functions/load_data.rs:327
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())
.headers(add_headers_from_args(headers)?)
.header(header::ACCEPT, file_format.as_accept_header());
if let Some(content_type) = post_content_type {
match HeaderValue::from_str(&content_type) {
Ok(c) => {
resp = resp.header(CONTENT_TYPE, c);
}
Err(_) => {
return Err(Error::message(format!(
"`load_data`: {} is an illegal content type",View on GitHub (pinned to 61d3082821)
Solutions
- Find and fix the original panic that poisoned the client mutex
- Use .unwrap_or_else(|p| p.into_inner()) to tolerate poisoning
- Store the reqwest Client without a Mutex (reqwest::Client is Arc internally and Sync) to eliminate the lock entirely
Example fix
// before
let response_client = self.client.lock().expect("response client lock");
// after
let response_client = self
.client
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner()); Defensive patterns
Strategy: try-catch
Try / catch
let response_client = match self.client.lock() {
Ok(c) => c,
Err(poisoned) => poisoned.into_inner(),
}; Prevention
- reqwest::Client is cheap to clone and Sync; store it directly instead of behind a Mutex
- Avoid panicking inside request-building code that runs while the lock is held
- Treat any PoisonError as a symptom: find and fix the original panicking request
When it happens
Trigger: A previous load_data URL request panicked while holding self.client (e.g. inside the request-building closure); the next remote-data call locks the poisoned mutex.
Common situations: Parallel template rendering of many remote loads where one thread panics (network/DNS panic path) and remaining renders cascade.
Related errors
- result cache lock
- Couldn't lock imageproc (set_base_url)
- Couldn't lock imageproc (num_img_ops)
- reqwest client build
- Couldn't lock imageproc (process_images)
AI-assisted analysis of getzola/zola@61d3082821 (2026-09-03).
Data as JSON: /api/errors/ac1739786592c9ed.
Report an issue: GitHub.