{"record":{"id":"15372a202bd23cb3","repo":"cjpais/Handy","slug":"failed-to-load-whisper-model","errorCode":null,"errorMessage":"Failed to load whisper model {}: {}","messagePattern":"Failed to load whisper model (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/managers/transcription.rs","lineNumber":575,"sourceCode":"                        emit_loading_failed(&e.to_string());\n                    })?,\n                    None => {\n                        let settings = get_settings(&self.app_handle);\n                        let accelerator = settings.transcribe_accelerator;\n                        (\n                            select_transcribe_backend(accelerator),\n                            resolve_gpu_device(accelerator, settings.transcribe_gpu_device),\n                        )\n                    }\n                };\n                let model_options = ModelOptions {\n                    backend,\n                    gpu_device,\n                };\n                let model = Model::load_with(&model_path, &model_options).map_err(|e| {\n                    let error_msg = format!(\"Failed to load whisper model {}: {}\", model_id, e);\n                    emit_loading_failed(&error_msg);\n                    anyhow::anyhow!(error_msg)\n                })?;\n                // The bound backend may differ from the request (e.g. CPU\n                // fallback under Auto); log what actually loaded.\n                let bound_backend = model.backend();\n                let session = model.session().map_err(|e| {\n                    let error_msg = format!(\n                        \"Failed to create session for whisper model {}: {}\",\n                        model_id, e\n                    );\n                    emit_loading_failed(&error_msg);\n                    anyhow::anyhow!(error_msg)\n                })?;\n                // Reconcile the registry's advertised capabilities with the\n                // loaded model's real ones (GGUF metadata) so badges/gating\n                // reflect runtime truth, not the pre-download probe. The\n                // load-completed event below triggers the frontend refresh.\n                let caps = session.model().capabilities();\n                self.model_manager.set_runtime_capabilities(","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/cjpais/Handy/blob/98a4d80cce8ad41efec2a419b59d9e81229a35d7/src-tauri/src/managers/transcription.rs#L557-L593","documentation":"transcribe-cpp's Model::load_with failed to load the Whisper-family GGUF with the selected backend and gpu_device (bound via select_transcribe_backend/resolve_gpu_device). The embedded inner error discriminates the cause: unsupported GGUF version or architecture, corrupted or truncated file, out-of-memory, or a GPU backend that cannot initialize. A loading_failed event is emitted with the composed message and the previously loaded engine has already been dropped.","triggerScenarios":"GGUF written by a newer converter than the vendored transcribe-cpp supports; a custom drop-in model with an unknown architecture; RAM/VRAM exhaustion on large models; Vulkan/Metal driver problems under the Auto accelerator; file locked by antivirus.","commonSituations":"Manually dropping in bleeding-edge GGUF quantizations; low-memory machines loading large or turbo models; broken GPU drivers after an OS update; loading right after a download that passed size but had no pinned hash.","solutions":["Read the embedded inner error first — it separates unsupported-format from OOM from backend failure","Switch the accelerator setting to CPU and retry to rule out Vulkan/Metal/driver issues","Free memory (close other apps) or choose a smaller model size/quantization","Re-download the model (delete_model + download_model) to rule out corruption, and update Handy for newer transcribe-cpp GGUF support"],"exampleFix":"// before\nlet model = Model::load_with(&model_path, &model_options)?;\n\n// after — retry the same file on CPU when a GPU backend fails to load\nlet model = match Model::load_with(&model_path, &model_options) {\n    Ok(m) => m,\n    Err(e) if !matches!(model_options.backend, Backend::Cpu) => {\n        warn!(\"GPU load failed ({}), falling back to CPU\", e);\n        Model::load_with(&model_path, &ModelOptions { backend: Backend::Cpu, gpu_device: 0 })?\n    }\n    Err(e) => return Err(anyhow::anyhow!(\"Failed to load whisper model {}: {}\", model_id, e)),\n};","handlingStrategy":"fallback","validationCode":"// Sanity-check the GGUF before loading: magic + non-trivial size\nfn looks_like_valid_gguf(path: &Path) -> bool {\n    let mut magic = [0u8; 4];\n    let Ok(mut f) = std::fs::File::open(path) else { return false };\n    use std::io::Read;\n    f.read_exact(&mut magic).is_ok() && &magic == b\"GGUF\" && path.metadata().map(|m| m.len() > 1_000_000).unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"let opts = ModelOptions { backend, gpu_device };\nlet model = match Model::load_with(&model_path, &opts) {\n    Ok(m) => m,\n    Err(e) if !matches!(backend, Backend::Cpu) => {\n        // GPU/backend load failure: degrade to CPU rather than failing the feature\n        emit_loading_failed(&format!(\"GPU load failed ({}), retrying on CPU\", e));\n        Model::load_with(&model_path, &ModelOptions { backend: Backend::Cpu, gpu_device: 0 })?\n    }\n    Err(e) => return Err(anyhow::anyhow!(\"Failed to load whisper model {}: {}\", model_id, e)),\n};","preventionTips":["Default large models to CPU on machines with weak or absent GPU stacks","Keep transcribe-cpp/vendor updated when using newly released GGUF formats","Verify custom GGUF drop-ins with the pinned sha256 before the first load","Watch free RAM/VRAM relative to model size before triggering a load"],"tags":["whisper","gguf","transcribe-cpp","model-loading","gpu-backend"],"backgroundTag":"model-load-failed","analyzedSha":"98a4d80cce8ad41efec2a419b59d9e81229a35d7","analyzedAt":"2026-08-16T20:58:09.966Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}