{"record":{"id":"2a1efe602e3f5eab","repo":"cjpais/Handy","slug":"transcription-engine-panicked-the-model-has-b","errorCode":null,"errorMessage":"Transcription engine panicked: {}. The model has been unloaded and will reload on next attempt.","messagePattern":"Transcription engine panicked: (.+?)\\. The model has been unloaded and will reload on next attempt\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/managers/transcription.rs","lineNumber":1470,"sourceCode":"                    {\n                        let mut current_model = self\n                            .current_model_id\n                            .lock()\n                            .unwrap_or_else(|e| e.into_inner());\n                        *current_model = None;\n                    }\n\n                    let _ = self.app_handle.emit(\n                        \"model-state-changed\",\n                        ModelStateEvent {\n                            event_type: \"unloaded\".to_string(),\n                            model_id: None,\n                            model_name: None,\n                            error: Some(format!(\"Engine panicked: {}\", panic_msg)),\n                        },\n                    );\n\n                    return Err(anyhow::anyhow!(\n                        \"Transcription engine panicked: {}. The model has been unloaded and will reload on next attempt.\",\n                        panic_msg\n                    ));\n                }\n            };\n\n            let output_language = with_model_detected_language(\n                resolve_output_language_evidence(\n                    &settings,\n                    applied_language_hint.as_deref(),\n                    &model_languages,\n                    output_was_translated,\n                ),\n                model_detected_language,\n            );\n            debug!(\"Output language evidence: {:?}\", output_language);\n\n            (text, output_language, model_languages)","sourceCodeStart":1452,"sourceCodeEnd":1488,"githubUrl":"https://github.com/cjpais/Handy/blob/ba10ce1943ef34e93c09494027fc0b9ced2e8a44/src-tauri/src/managers/transcription.rs#L1452-L1488","documentation":"The engine call is wrapped in catch_unwind(AssertUnwindSafe(...)); this error fires when the native engine (GGML or ONNX Runtime code) panicked instead of returning Err. On panic the engine is deliberately not put back (mutex stays unpoisoned), a model-state-changed \"unloaded\" event is emitted with \"Engine panicked: {msg}\", and the error promises the model reloads on the next attempt.","triggerScenarios":"Any panic inside the matched engine arm: native assertions in transcribe-cpp/transcribe-rs (index out of bounds, unwrap on None), audio containing NaN/inf samples driving a panic in DSP code, or FFI-level crashes surfaced as Rust panics.","commonSituations":"Buggy engine version for a newly added arch; pathological audio (silence, clipping, corrupt float samples); edge-case sample rates; bugs fixed in later library updates.","solutions":["Simply retry once — the engine was unloaded and the next transcribe attempt reloads the model","Read the panic message in the log to identify the native assertion; search the Handy tracker for that message","Update the app (bundles newer transcribe-cpp/transcribe-rs with panic fixes)","Switch to a different engine/model to keep working while the panic is investigated","Report with logs if reproducible — include audio conditions (length, device, sample rate)"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// sanitize audio before it reaches native code\nlet clean: Vec<f32> = audio.iter().map(|s| if s.is_finite() { *s } else { 0.0 }).collect();","typeGuard":null,"tryCatchPattern":"match manager.transcribe(audio.clone()) {\n    Err(e) if e.to_string().starts_with(\"Transcription engine panicked\") => {\n        // engine was unloaded; a fresh attempt reloads the model — retry exactly once\n        manager.transcribe(audio)\n    }\n    other => other,\n}","preventionTips":["Always retry once after this error — recovery is by design (reload on next attempt)","Report reproducible panics with the panic message and audio conditions","Update the app to pick up engine panic fixes","Switch engines to keep working while a reproducible panic is investigated"],"tags":["rust","panic","catch-unwind","native","recovery"],"backgroundTag":"native-library-panic","analyzedSha":"ba10ce1943ef34e93c09494027fc0b9ced2e8a44","analyzedAt":"2026-08-17T10:29:55.597Z","contentChangedAt":"2026-08-17T10:29:55.597Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}