{"record":{"id":"737e4b95b54dbf15","repo":"aaif-goose/goose","slug":"failed-to-acquire-registry-lock","errorCode":null,"errorMessage":"Failed to acquire registry lock","messagePattern":"Failed to acquire registry lock","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/cli.rs","lineNumber":2150,"sourceCode":"\n            println!(\n                \"\\nDownloaded {} ({}). Registering...\",\n                model_id,\n                if total_size > 0 {\n                    format!(\"{:.1}GB\", total_size as f64 / (1024.0 * 1024.0 * 1024.0))\n                } else {\n                    \"unknown size\".to_string()\n                }\n            );\n\n            let model_id = hf_models::register_resolved_model(resolved, &spec)?;\n\n            println!(\"Registered: {}\", model_id);\n        }\n        LocalModelsCommand::List => {\n            let registry = get_registry()\n                .lock()\n                .map_err(|_| anyhow::anyhow!(\"Failed to acquire registry lock\"))?;\n            let models = registry.list_models();\n\n            if models.is_empty() {\n                println!(\"No local models downloaded.\");\n                return Ok(());\n            }\n\n            println!(\n                \"{:<50} {:<10} {:<12} Downloaded\",\n                \"ID\", \"Backend\", \"Variant\"\n            );\n            println!(\"{}\", \"-\".repeat(88));\n            for m in models {\n                println!(\n                    \"{:<50} {:<10} {:<12} {}\",\n                    m.id,\n                    m.backend_id.as_deref().unwrap_or(\"llamacpp\"),\n                    m.quantization,","sourceCodeStart":2132,"sourceCodeEnd":2168,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/cli.rs#L2132-L2168","documentation":"The local-models registry is guarded by a std Mutex. `lock()` returns Err when the mutex is poisoned — meaning some thread panicked while holding it — and the `goose local-models list` handler maps that poisoned-lock error to this message instead of listing models.","triggerScenarios":"Running `goose local-models list` in a process where an earlier panic occurred on a thread holding the registry mutex, e.g. a model registration or download step that panicked mid-write.","commonSituations":"A crashed/interrupted `goose local-models download` within the same invocation; registry persistence panics; same-process concurrent access to the registry.","solutions":["Re-run the command — a fresh process gets a fresh, un-poisoned mutex","Avoid running multiple goose commands that touch the local-models registry simultaneously","If it recurs, capture the original panic message from logs (the poison's root cause) and report it upstream","As a last resort, reset local model registry state and re-register the models"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"# Rust: recover from a poisoned lock instead of aborting\nmatch get_registry().lock() {\n    Ok(reg) => { let _ = reg.list_models(); }\n    Err(poisoned) => {\n        let reg = poisoned.into_inner(); // registry state is still inspectable\n        let _ = reg.list_models();\n    }\n}","preventionTips":["Serialize local-models operations across scripts","Treat a poisoned lock as a symptom: find and report the panic that poisoned it","Re-run the command in a fresh process before assuming data loss"],"tags":["local-models","mutex","concurrency","panic","cli"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}