cjpais/Handy · error · anyhow::Error
Failed to extract archive
Error message
Failed to extract archive: {} What it means
Extraction of a downloaded archive-based (directory) model failed: the inner extraction block captures the error as error_msg, emits the model-extraction-failed event with the model_id and error, removes the model from the extracting set, and rethrows via `anyhow::anyhow!(error_msg)`. Extraction runs into a temp dir which is then moved to the final model dir, so failures are typically a corrupt archive or filesystem problems.
Solutions
- Delete the model entry and its leftover files, then re-download — a fresh archive fixes corruption
- Free disk space: budget for archive plus extracted content simultaneously
- Check temp dir and models dir permissions; on Windows, add an antivirus exclusion for the models dir
- Listen for the model-extraction-failed event in the UI to surface the detailed error to the user
Defensive patterns
Strategy: retry
Validate before calling
// require room for archive + extracted copy before starting
fn disk_space_sufficient(models_dir: &Path, model_bytes: u64) -> bool {
// rough rule: 2.2x the archive size covers download + extract + move
fs2::available_space(models_dir).map(|f| f > model_bytes * 2).unwrap_or(false)
} Try / catch
if let Err(e) = install.extract() {
// error_msg already emitted as model-extraction-failed; a clean re-download is the fix
let _ = manager.delete_model(model_id);
manager.download_model(model_id).await?; // retry once with a fresh archive
} Prevention
- Verify the archive checksum (sha256 already known for Url models) before extracting
- Extract to the same filesystem as the final dir so the move can't fail across devices
- Subscribe to the model-extraction-failed event in the UI to show the detailed cause
When it happens
Trigger: Truncated/corrupted archive from an interrupted or bit-rotted download; unsupported compression method inside the zip; disk full during extraction (archive + extracted copy coexist); temp dir or destination permissions; antivirus/locked files on Windows mid-extract.
Common situations: Download 'completed' but the file was cut short by a stall; extracting multi-GB models on a nearly-full disk; EDR software quarantining or locking extracted binaries; extracting into a read-only or roaming-profile directory.
Related errors
- Complete model directory not found
- Model is currently downloading
- Model not available
- No model files found to delete
- Canary transcription failed
AI-assisted analysis of cjpais/Handy@ba10ce1943 (2026-08-17).
Data as JSON: /api/errors/7c73d6e9bffaafe1.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/managers/model.rs:2330
let error_msg = format!("Failed to extract archive: {}", e);
// Clean up failed extraction
let _ = fs::remove_dir_all(&temp_extract_dir);
// Delete the corrupt partial file so the next download attempt starts fresh
// instead of resuming from a broken archive (issue #858).
let _ = fs::remove_file(&partial_path);
// Remove from extracting set
{
let mut extracting = self.extracting_models.lock().unwrap();
extracting.remove(model_id);
}
let _ = self.app_handle.emit(
"model-extraction-failed",
&serde_json::json!({
"model_id": model_id,
"error": error_msg
}),
);
anyhow::anyhow!(error_msg)
})?;
// Find the actual extracted directory (archive might have a nested structure)
let extracted_dirs: Vec<_> = fs::read_dir(&temp_extract_dir)?
.filter_map(|entry| entry.ok())
.filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false))
.collect();
if extracted_dirs.len() == 1 {
// Single directory extracted, move it to the final location
let source_dir = extracted_dirs[0].path();
if final_model_dir.exists() {
fs::remove_dir_all(&final_model_dir)?;
}
fs::rename(&source_dir, &final_model_dir)?;
// Clean up temp directory
let _ = fs::remove_dir_all(&temp_extract_dir);
} else {View on GitHub (pinned to ba10ce1943)