cjpais/Handy · error · anyhow::Error
Complete model file not found: {}
Error message
Complete model file not found: {} What it means
For file-based (non-HF) models, get_model_path returns models_dir/<filename> only when that file exists and no <filename>.partial sits alongside it (the .partial proves an unfinished transfer). This error means the target file is missing or a partial marker taints it.
Source
Thrown at src-tauri/src/managers/model.rs:2534
.models_dir
.join(format!("{}.partial", &model_info.filename));
if model_info.is_directory {
// For directory-based models, ensure the directory exists and is complete
if model_path.exists() && model_path.is_dir() && !partial_path.exists() {
Ok(model_path)
} else {
Err(anyhow::anyhow!(
"Complete model directory not found: {}",
model_id
))
}
} else {
// For file-based models (existing logic)
if model_path.exists() && !partial_path.exists() {
Ok(model_path)
} else {
Err(anyhow::anyhow!(
"Complete model file not found: {}",
model_id
))
}
}
}
pub fn cancel_download(&self, model_id: &str) -> Result<()> {
debug!("ModelManager: cancel_download called for: {}", model_id);
// Trigger the cancellation token to stop the download. The HF path
// aborts its in-flight chunk tasks and unwinds promptly; the URL path
// observes it on the next chunk of its stream loop.
{
let flags = self.cancel_flags.lock().unwrap();
if let Some(token) = flags.get(model_id) {
token.cancel();
info!("Cancellation token triggered for: {}", model_id);View on GitHub (pinned to 98a4d80cce)
Solutions
- Remove the stale <filename>.partial marker if the target file is verifiably complete, then retry
- Re-download via delete_model(model_id) + download_model(model_id) to obtain a hash-verified complete file
- Confirm the file name matches model_info.filename exactly (no .partial suffix, no rename) inside models_dir
Defensive patterns
Strategy: validation
Validate before calling
let Some(info) = model_manager.get_model_info(model_id) else {
anyhow::bail!("Model not found: {}", model_id);
};
if !info.is_directory {
let file = model_manager.models_dir.join(&info.filename);
let partial = model_manager.models_dir.join(format!("{}.partial", info.filename));
if !(file.is_file() && !partial.exists()) {
return re_download(model_id).await;
}
} Type guard
fn file_model_complete(mm: &ModelManager, filename: &str) -> bool {
let file = mm.models_dir.join(filename);
let partial = mm.models_dir.join(format!("{}.partial", filename));
file.is_file() && !partial.exists()
} Try / catch
match model_manager.get_model_path(model_id) {
Ok(p) => Ok(p),
Err(e) if e.to_string().starts_with("Complete model file not found") => {
// file missing or tainted by a .partial marker: re-download verified bytes
download_model_and_wait(model_id).await?;
model_manager.get_model_path(model_id)
}
Err(e) => Err(e),
} Prevention
- Exclude the models directory from antivirus quarantine so files are not silently removed
- Never rename model files in the models dir — names must match the catalog exactly
- After a failed download, prefer delete_model + download_model over manual cleanup
When it happens
Trigger: An interrupted download left <filename>.partial next to a missing/incomplete target; the GGUF/ONNX file was deleted, moved, or renamed after being marked downloaded; models_dir location changed.
Common situations: Killing the app mid-download; antivirus quarantining a large model file; users manually cleaning the models folder; restoring settings on a new machine without the model files.
Related errors
- Complete model directory not found: {}
- Model is currently downloading: {}
- Complete model file not found in HF cache or models dir: {}
- Model not downloaded
AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16).
Data as JSON: /api/errors/26c78c9520e1dd3a.
Report an issue: GitHub.