cjpais/Handy · error · anyhow::Error
Complete model file not found in HF cache or models dir
Error message
Complete model file not found in HF cache or models dir: {} What it means
An HuggingFace-sourced model is flagged downloaded, but neither the HF cache snapshot path (hf_cached_path) nor the file in models_dir exists. The manager treats the HF cache as externally owned: if the user wipes it (or the snapshot pointer is broken) while is_downloaded stays true, the state lies and this error exposes it. Note the code already tolerates a stale .partial next to an existing local file and cleans it up — this error means there is genuinely no complete file anywhere.
Solutions
- Delete and re-download the model — this resets is_downloaded and restores the cache entry
- Restore the HF cache blob/snapshot from backup if you have one
- Manually place the model file in the models dir under model_info.filename (manual drop-ins are supported)
- As a maintainer: on this error, auto-clear is_downloaded so the UI immediately shows the re-download action
Defensive patterns
Strategy: fallback
Validate before calling
// verify the file actually exists before trusting is_downloaded
let path = hf_cached_path(&repo_id, &revision, &filename)
.or_else(|| {
let p = self.models_dir.join(&filename);
p.exists().then_some(p)
})
.ok_or_else(|| anyhow::anyhow!("HF model {model_id} missing from disk — re-download"))?
// (get_model_path already implements exactly this check — call it, don't cache stale paths)
let _ = std::fs::metadata(&path)?; // resolve symlinked blobs eagerly Try / catch
match manager.get_model_path(id) {
Err(e) if e.to_string().contains("not found in HF cache") => {
// re-download resets the stale is_downloaded flag
manager.delete_model(id)?;
manager.download_model(id).await?;
}
other => other?,
} Prevention
- Never cache resolved model paths across sessions — re-resolve via get_model_path each time
- If you wipe the HF cache externally, delete the model in-app first so flags stay honest
- Clear is_downloaded automatically when this error is hit, so the UI offers re-download immediately
When it happens
Trigger: User deleted ~/.cache/huggingface (or ran huggingface-cli delete-cache) while the app was closed; alternate-quant blob removed but snapshot pointer remained; models dir moved/restored from backup without the model; app data copied between machines without the HF cache.
Common situations: Disk-space cleanup tools wiping HF caches; migrating installs; file sync conflicts removing large blobs.
Related errors
- Complete model directory not found
- Download failed from Hugging Face
- Failed to init Hugging Face API
- Hugging Face download failed after
- No model files found to delete
AI-assisted analysis of cjpais/Handy@ba10ce1943 (2026-09-17).
Data as JSON: /api/errors/34f32ba071576f34.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/managers/model.rs:2598
if let Some(path) = hf_cached_path(repo_id, revision, &model_info.filename) {
return Ok(path);
}
// Mirror-fallback download or manual drop-in in the models dir.
// The complete file only ever appears after verification, so a
// stale `.partial` alongside it is leftover noise, not a veto —
// clear it rather than declaring the model missing.
let local_path = self.models_dir.join(&model_info.filename);
if local_path.exists() {
let partial_path = self
.models_dir
.join(format!("{}.partial", &model_info.filename));
if partial_path.exists() {
let _ = fs::remove_file(&partial_path);
}
return Ok(local_path);
}
self.mark_model_unavailable(model_id);
return Err(anyhow::anyhow!(
"Complete model file not found in HF cache or models dir: {}",
model_id
));
}
let model_path = self.models_dir.join(&model_info.filename);
let partial_path = self
.models_dir
.join(format!("{}.partial", &model_info.filename));
if model_info.is_directory {
if !model_path.exists() || !model_path.is_dir() {
self.mark_model_unavailable(model_id);
return Err(anyhow::anyhow!(
"Complete model directory not found: {}",
model_id
));
}View on GitHub (pinned to ba10ce1943)