{"record":{"id":"26c78c9520e1dd3a","repo":"cjpais/Handy","slug":"complete-model-file-not-found","errorCode":null,"errorMessage":"Complete model file not found: {}","messagePattern":"Complete model file not found: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/managers/model.rs","lineNumber":2534,"sourceCode":"            .models_dir\n            .join(format!(\"{}.partial\", &model_info.filename));\n\n        if model_info.is_directory {\n            // For directory-based models, ensure the directory exists and is complete\n            if model_path.exists() && model_path.is_dir() && !partial_path.exists() {\n                Ok(model_path)\n            } else {\n                Err(anyhow::anyhow!(\n                    \"Complete model directory not found: {}\",\n                    model_id\n                ))\n            }\n        } else {\n            // For file-based models (existing logic)\n            if model_path.exists() && !partial_path.exists() {\n                Ok(model_path)\n            } else {\n                Err(anyhow::anyhow!(\n                    \"Complete model file not found: {}\",\n                    model_id\n                ))\n            }\n        }\n    }\n\n    pub fn cancel_download(&self, model_id: &str) -> Result<()> {\n        debug!(\"ModelManager: cancel_download called for: {}\", model_id);\n\n        // Trigger the cancellation token to stop the download. The HF path\n        // aborts its in-flight chunk tasks and unwinds promptly; the URL path\n        // observes it on the next chunk of its stream loop.\n        {\n            let flags = self.cancel_flags.lock().unwrap();\n            if let Some(token) = flags.get(model_id) {\n                token.cancel();\n                info!(\"Cancellation token triggered for: {}\", model_id);","sourceCodeStart":2516,"sourceCodeEnd":2552,"githubUrl":"https://github.com/cjpais/Handy/blob/98a4d80cce8ad41efec2a419b59d9e81229a35d7/src-tauri/src/managers/model.rs#L2516-L2552","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let Some(info) = model_manager.get_model_info(model_id) else {\n    anyhow::bail!(\"Model not found: {}\", model_id);\n};\nif !info.is_directory {\n    let file = model_manager.models_dir.join(&info.filename);\n    let partial = model_manager.models_dir.join(format!(\"{}.partial\", info.filename));\n    if !(file.is_file() && !partial.exists()) {\n        return re_download(model_id).await;\n    }\n}","typeGuard":"fn file_model_complete(mm: &ModelManager, filename: &str) -> bool {\n    let file = mm.models_dir.join(filename);\n    let partial = mm.models_dir.join(format!(\"{}.partial\", filename));\n    file.is_file() && !partial.exists()\n}","tryCatchPattern":"match model_manager.get_model_path(model_id) {\n    Ok(p) => Ok(p),\n    Err(e) if e.to_string().starts_with(\"Complete model file not found\") => {\n        // file missing or tainted by a .partial marker: re-download verified bytes\n        download_model_and_wait(model_id).await?;\n        model_manager.get_model_path(model_id)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["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"],"tags":["partial-download","filesystem","file-model","model-download"],"backgroundTag":"partial-download-leftover","analyzedSha":"98a4d80cce8ad41efec2a419b59d9e81229a35d7","analyzedAt":"2026-08-16T20:58:09.966Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}