{"record":{"id":"c2cf2e447690f6ba","repo":"Zackriya-Solutions/meetily","slug":"unsupported-model-for-download-validation","errorCode":null,"errorMessage":"Unsupported model for download validation: {}","messagePattern":"Unsupported model for download validation: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"frontend/src-tauri/src/whisper_engine/whisper_engine.rs","lineNumber":990,"sourceCode":"                let expected_min_size = WHISPER_MODEL_CATALOG\n                    .iter()\n                    .find(|model| model.0 == model_name)\n                    .map(|model| ((model.2 as f64 * 0.9) as u64) * 1024 * 1024);\n\n                result = match expected_min_size {\n                    Some(expected_min_size) => match fs::metadata(file_path).await {\n                        Ok(metadata) if metadata.len() >= expected_min_size => Ok(()),\n                        Ok(metadata) => Err(anyhow!(\n                            \"Downloaded model file is too small: {} bytes (expected at least {} bytes)\",\n                            metadata.len(),\n                            expected_min_size\n                        )),\n                        Err(e) => Err(anyhow!(\n                            \"Failed to read downloaded model file metadata: {}\",\n                            e\n                        )),\n                    },\n                    None => Err(anyhow!(\n                        \"Unsupported model for download validation: {}\",\n                        model_name\n                    )),\n                };\n            }\n        }\n\n        if result.is_err() && !active_download.cancellation.is_cancelled() && file_path.exists() {\n            if let Err(e) = fs::remove_file(file_path).await {\n                log::warn!(\"Failed to clean up failed download file: {}\", e);\n            } else {\n                log::info!(\"Cleaned up failed download file: {}\", file_path.display());\n            }\n        }\n\n        let (released_active_owner, cancellation_won) = {\n            let mut active_downloads = self.active_downloads.lock().await;\n            match active_downloads.get(model_name) {","sourceCodeStart":972,"sourceCodeEnd":1008,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/a2cb62e827da7ef59f65064c97233efb2313878e/frontend/src-tauri/src/whisper_engine/whisper_engine.rs#L972-L1008","documentation":"finish_download derives the minimum acceptable file size by looking the model name up in WHISPER_MODEL_CATALOG. If the name is not in the catalog, expected_min_size is None and this error is thrown: the app cannot validate a download for a model it has no size metadata for. Downloading via the public download_model() can't hit it (names are pre-validated against the URL match), so it indicates a name/catalog mismatch, typically via download_model_from_url or a stale catalog.","triggerScenarios":"download_model_from_url() is called (directly or by a test/future code path) with a model_name string that has no entry in WHISPER_MODEL_CATALOG, or the catalog entry was removed/renamed while download_model()'s URL match arm still accepts the old name.","commonSituations":"Developer adds a new model to download_model()'s URL match but forgets to add it to WHISPER_MODEL_CATALOG; a model is renamed in the catalog but old UI/config still passes the old name; custom code or tests invoke download_model_from_url with an ad-hoc name.","solutions":["Add an entry for the model name to WHISPER_MODEL_CATALOG (name, url/key, size in MB) so min-size validation can run.","Ensure download_model()'s URL match and WHISPER_MODEL_CATALOG use identical names — make one the single source of truth.","Verify the exact model_name string being passed (typos, old names like 'large' vs 'large-v3') — it must match a catalog key exactly.","If the model genuinely has no known size, either skip validation for it explicitly or register a conservative minimum size."],"exampleFix":"// before: URL table knows the name but catalog doesn't\n\"large-v3-turbo\" => \"https://huggingface.co/.../ggml-large-v3-turbo.bin\",\n// WHISPER_MODEL_CATALOG: missing (\"large-v3-turbo\", url, size) entry\n// after: add the catalog entry so finish_download can validate\n// WHISPER_MODEL_CATALOG\n(\"large-v3-turbo\", \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin\", 1620),","handlingStrategy":"validation","validationCode":"fn is_downloadable_model(model_name: &str) -> bool {\n    WHISPER_MODEL_CATALOG.iter().any(|(name, _, _)| *name == model_name)\n}\n// call before starting a download:\nassert!(is_downloadable_model(\"large-v3-turbo\"), \"model not in catalog\");","typeGuard":"fn catalog_entry(model_name: &str) -> Option<&( &'static str, &'static str, u64 )> {\n    WHISPER_MODEL_CATALOG.iter().find(|(name, _, _)| *name == model_name)\n}","tryCatchPattern":"match download_result {\n    Err(e) if e.to_string().contains(\"Unsupported model for download validation\") => {\n        // name/catalog mismatch: surface which names ARE valid\n        Err(anyhow!(\"unknown model '{}'; valid: {:?}\", model_name,\n            WHISPER_MODEL_CATALOG.iter().map(|(n, _, _)| *n).collect::<Vec<_>>()))\n    }\n    other => other,\n}","preventionTips":["Make WHISPER_MODEL_CATALOG the single source of truth; derive download_model()'s URL match from it.","Add a unit test asserting every name accepted by download_model() exists in WHISPER_MODEL_CATALOG.","Validate user/model-picker input against the catalog before invoking any download API.","When renaming a model, update catalog, URL table, and persisted UI settings together."],"tags":["configuration","catalog","model-download","rust","whisper"],"backgroundTag":"unsupported-operation","analyzedSha":"a2cb62e827da7ef59f65064c97233efb2313878e","analyzedAt":"2026-09-12T11:12:14.152Z","contentChangedAt":"2026-09-12T11:12:14.152Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}