{"record":{"id":"2e0ddbaccc31fc44","repo":"Zackriya-Solutions/meetily","slug":"unsupported-model","errorCode":null,"errorMessage":"Unsupported model: {}","messagePattern":"Unsupported model: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"frontend/src-tauri/src/whisper_engine/whisper_engine.rs","lineNumber":941,"sourceCode":"            // Standard f16 models\n            \"tiny\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.bin\",\n            \"base\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin\",\n            \"small\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin\",\n            \"medium\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-medium.bin\",\n            \"large-v3-turbo\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin\",\n            \"large-v3\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3.bin\",\n\n            // Q5_1 quantized models\n            \"tiny-q5_1\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny-q5_1.bin\",\n            \"base-q5_1\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base-q5_1.bin\",\n            \"small-q5_1\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small-q5_1.bin\",\n\n            // Q5_0 quantized models\n            \"medium-q5_0\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-medium-q5_0.bin\",\n            \"large-v3-turbo-q5_0\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo-q5_0.bin\",\n            \"large-v3-q5_0\" => \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-q5_0.bin\",\n\n            _ => return Err(anyhow!(\"Unsupported model: {}\", model_name))\n        };\n        \n        log::info!(\"Model URL for {}: {}\", model_name, model_url);\n        \n        // Generate correct filename - all models follow ggml-{model_name}.bin pattern\n        let filename = format!(\"ggml-{}.bin\", model_name);\n        let file_path = self.models_dir.join(&filename);\n        \n        log::info!(\"Downloading to file path: {}\", file_path.display());\n        \n        // Create models directory if it doesn't exist\n        if !self.models_dir.exists() {\n            fs::create_dir_all(&self.models_dir).await\n                .map_err(|e| anyhow!(\"Failed to create models directory: {}\", e))?;\n        }\n        \n        // Update model status to downloading\n        {","sourceCodeStart":923,"sourceCodeEnd":959,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/whisper_engine/whisper_engine.rs#L923-L959","documentation":"download_model maps a fixed set of model names to official ggerganov/whisper.cpp HuggingFace URLs via a match; any other string hits the default arm and is rejected before any network I/O. Supported keys: tiny, base, small, medium, large-v3-turbo, large-v3, tiny-q5_1, base-q5_1, small-q5_1, medium-q5_0, large-v3-turbo-q5_0, large-v3-q5_0. Matching is exact and case-sensitive.","triggerScenarios":"Passing 'large' or 'turbo' (not real keys); casing mistakes like 'Base'; wrong quantization suffix ('medium-q5_1' does not exist — only medium-q5_0); passing an arbitrary HuggingFace repo id.","commonSituations":"Frontend model list out of sync with the Rust catalog after a version update; user typing a custom model name; scripts hardcoding names from older releases (e.g. 'large-v2' was never added here).","solutions":["Use one of the exact supported keys listed above, byte-for-byte","Fetch the model list from the engine (get_whisper_models) and only offer those ids in the UI","To add a new model, extend both this match arm with its URL and the frontend catalog, keeping the ggml-<key>.bin naming convention"],"exampleFix":"// before\nawait invoke('download_model', { modelName: 'medium-q5_1' }); // unsupported\n\n// after\nawait invoke('download_model', { modelName: 'medium-q5_0' }); // real key","handlingStrategy":"validation","validationCode":"const SUPPORTED = ['tiny','base','small','medium','large-v3-turbo','large-v3',\n  'tiny-q5_1','base-q5_1','small-q5_1','medium-q5_0','large-v3-turbo-q5_0','large-v3-q5_0'];\nif (!SUPPORTED.includes(modelName)) {\n  throw new Error(`Unsupported model '${modelName}'. Supported: ${SUPPORTED.join(', ')}`);\n}\nawait invoke('download_model', { modelName });","typeGuard":"const isSupportedModel = (name: string): name is typeof SUPPORTED[number] =>\n  SUPPORTED.includes(name as any);","tryCatchPattern":"try {\n  await invoke('download_model', { modelName });\n} catch (e) {\n  if (String(e).includes('Unsupported model')) { showSupportedModelList(); } else { throw e; }\n}","preventionTips":["Render the model picker exclusively from get_whisper_models output so the UI can never send an unknown key","When adding models, update the Rust match and every hardcoded frontend list in the same change","Reject free-text model names at the input layer; offer a dropdown instead"],"tags":["whisper","model-management","validation","rust","huggingface"],"backgroundTag":"invalid-model-identifier","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}