aaif-goose/goose · error
Failed to acquire lock
Error message
Failed to acquire lock
What it means
The download manager guards its shared HashMap with a std::sync::Mutex; reserve_download maps a poisoned lock to 'Failed to acquire lock'. Only poisoning — another thread panicking while holding the lock — causes this; a contended but healthy lock simply blocks. Note sibling methods (set_progress, update_progress) silently ignore the same condition.
Source
Thrown at crates/goose-download-manager/src/lib.rs:130
pub fn list_progress(&self) -> Vec<DownloadProgress> {
self.downloads
.lock()
.map(|downloads| downloads.values().cloned().collect())
.unwrap_or_default()
}
pub fn set_progress(&self, progress: DownloadProgress) {
if let Ok(mut downloads) = self.downloads.lock() {
downloads.insert(progress.model_id.clone(), progress);
}
}
pub fn reserve_download(&self, progress: DownloadProgress) -> Result<bool> {
let mut downloads = self
.downloads
.lock()
.map_err(|_| anyhow::anyhow!("Failed to acquire lock"))?;
if let Some(existing) = downloads.get(&progress.model_id) {
if existing.status == DownloadStatus::Downloading
|| (existing.status == DownloadStatus::Cancelled && !existing.task_exited)
{
return Ok(false);
}
}
downloads.insert(progress.model_id.clone(), progress);
Ok(true)
}
pub fn update_progress(&self, model_id: &str, update: impl FnOnce(&mut DownloadProgress)) {
if let Ok(mut downloads) = self.downloads.lock() {
if let Some(progress) = downloads.get_mut(model_id) {
update(progress);
}View on GitHub (pinned to 3810898a74)
Solutions
- Update goose — a panic under this lock is a defect worth reporting with logs
- Recreate the DownloadManager (restart the process) to obtain a fresh, unpoisoned lock
- Capture the first panic's log to find the poisoning site
Defensive patterns
Strategy: fallback
Try / catch
let ok = match manager.reserve_download(progress) {
Ok(reserved) => reserved,
Err(e) if e.to_string() == "Failed to acquire lock" => {
// poisoned lock: fall back to a fresh manager
let fresh = DownloadManager::new();
fresh.reserve_download(progress)?
}
Err(e) => return Err(e),
}; Prevention
- Report panics originating in download bookkeeping — they poison this lock for everyone
- Design call sites to recreate the manager rather than retry the same poisoned one
- Monitor for the first panic; the lock error is only a symptom
When it happens
Trigger: Any thread panicking while holding self.downloads (for example a download task unwinding inside a lock scope); every subsequent reserve_download call then fails.
Common situations: Rare internal failure following a panic in download bookkeeping; not reachable through ordinary API misuse.
Related errors
- Failed to acquire registry lock
- Download already in progress
- Download is being cancelled; wait for it to finish before re
- Failed to acquire registry lock
- Failed to acquire registry lock
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/ea5bb6de096e251c.
Report an issue: GitHub.