{"record":{"id":"da75a47e038d118f","repo":"cjpais/Handy","slug":"complete-model-directory-not-found","errorCode":null,"errorMessage":"Complete model directory not found: {}","messagePattern":"Complete model directory not found: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/managers/model.rs","lineNumber":2524,"sourceCode":"                return Ok(local_path);\n            }\n            return Err(anyhow::anyhow!(\n                \"Complete model file not found in HF cache or models dir: {}\",\n                model_id\n            ));\n        }\n\n        let model_path = self.models_dir.join(&model_info.filename);\n        let partial_path = self\n            .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<()> {","sourceCodeStart":2506,"sourceCodeEnd":2542,"githubUrl":"https://github.com/cjpais/Handy/blob/98a4d80cce8ad41efec2a419b59d9e81229a35d7/src-tauri/src/managers/model.rs#L2506-L2542","documentation":"For directory-based (non-HF) models, get_model_path requires models_dir/<filename> to exist as a directory AND no <filename>.partial marker file next to it. The .partial file is the download-in-progress sentinel; its presence vetoes the directory even if its contents look complete. This error fires when the directory is missing or the sentinel taints it.","triggerScenarios":"An interrupted directory download (e.g. a Parakeet ONNX bundle) left <filename>.partial behind; the directory was deleted or never fully written; registry says is_downloaded but the directory is absent.","commonSituations":"App killed mid-download of a directory model; user pruned the models folder; disk-full abort while extracting the bundle.","solutions":["If the directory is actually complete, delete the stale <filename>.partial file and retry","Otherwise re-download: delete_model(model_id) then download_model(model_id), which recreates the directory and clears the marker","Verify models_dir actually points at the location holding the model directory, then rescan_local_models"],"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 dir = model_manager.models_dir.join(&info.filename);\n    let partial = model_manager.models_dir.join(format!(\"{}.partial\", info.filename));\n    if !(dir.is_dir() && !partial.exists()) {\n        // incomplete directory model — trigger a fresh download instead of loading\n        return re_download(model_id).await;\n    }\n}","typeGuard":"fn directory_model_complete(mm: &ModelManager, filename: &str) -> bool {\n    let dir = mm.models_dir.join(filename);\n    let partial = mm.models_dir.join(format!(\"{}.partial\", filename));\n    dir.is_dir() && !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 directory not found\") => {\n        // safest fallback: remove any stale marker/directory and re-download\n        cleanup_partial_markers(model_id);\n        download_model_and_wait(model_id).await?;\n        model_manager.get_model_path(model_id)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Treat any <filename>.partial next to a directory model as an incomplete download","Cancel downloads through cancel_download so markers are cleaned up by the RAII guard","Run rescan_local_models after manually touching the models directory"],"tags":["partial-download","filesystem","directory-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"}