{"record":{"id":"b0ee8aa8a7de5c9f","repo":"Zackriya-Solutions/meetily","slug":"no-model-loaded-please-load-a-model-first","errorCode":null,"errorMessage":"No model loaded. Please load a model first.","messagePattern":"No model loaded\\. Please load a model first\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"frontend/src-tauri/src/whisper_engine/whisper_engine.rs","lineNumber":519,"sourceCode":"            return 0.0;\n        }\n\n        let mut word_counts = HashMap::new();\n        for word in &words {\n            *word_counts.entry(word.to_lowercase()).or_insert(0) += 1;\n        }\n\n        let total_words = words.len() as f32;\n        let repeated_words: usize = word_counts.values().map(|&count| if count > 1 { count - 1 } else { 0 }).sum();\n\n        repeated_words as f32 / total_words\n    }\n    \n    /// Transcribe audio with streaming support for partial results and adaptive quality\n    pub async fn transcribe_audio_with_confidence(&self, audio_data: Vec<f32>, language: Option<String>) -> Result<(String, f32, bool)> {\n        let ctx_lock = self.current_context.read().await;\n        let ctx = ctx_lock.as_ref()\n            .ok_or_else(|| anyhow!(\"No model loaded. Please load a model first.\"))?;\n\n        // Get adaptive configuration based on hardware\n        let hardware_profile = crate::audio::HardwareProfile::detect();\n        let adaptive_config = hardware_profile.get_whisper_config();\n\n        // ADAPTIVE parameters - optimized for current hardware\n        let mut params = FullParams::new(SamplingStrategy::BeamSearch {\n            beam_size: adaptive_config.beam_size as i32,\n            patience: 1.0\n        });\n\n        // Configure with adaptive settings\n        // If language is \"auto\" or None, use automatic language detection (pass None)\n        // If language is \"auto-translate\", enable translation to English\n        // Otherwise, use the specified language code\n        let (language_code, should_translate) = match language.as_deref() {\n            Some(\"auto\") | None => (None, false),\n            Some(\"auto-translate\") => (None, true),","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/whisper_engine/whisper_engine.rs#L501-L537","documentation":"transcribe_audio_with_confidence acquires a read lock on self.current_context and finds None: no whisper context is loaded in this process. The engine keeps exactly one loaded model in memory, and it does not auto-load. This is the guard before any whisper.cpp work starts.","triggerScenarios":"Calling transcribe_audio_with_confidence (transcription path of the recording pipeline) before any successful load_model; after unload_model; after a load_model attempt that returned Missing/Downloading/Error/Corrupted.","commonSituations":"App restart clears the in-memory context even though models exist on disk; user starts recording before the model finishes loading; model auto-load at startup is not awaited before the audio pipeline begins emitting chunks.","solutions":["Await a successful load_model(model_name) before starting recording or feeding audio chunks","Gate the Record button on the model-loaded state event instead of assuming a model is present","Persist the last-used model name and load it automatically at app startup, blocking transcription until it completes"],"exampleFix":"// before\nstartRecording();                       // audio arrives, engine has no context\nawait invoke('load_whisper_model', { modelName });\n\n// after\nawait invoke('load_whisper_model', { modelName });\nstartRecording();","handlingStrategy":"validation","validationCode":"// Frontend: only start recording when a model is loaded\nconst loaded = await invoke<boolean>('is_whisper_model_loaded'); // or track via state events\nif (!loaded) {\n  await invoke('load_whisper_model', { modelName: lastUsedModel });\n}\nawait invoke('start_recording', { /* ... */ });","typeGuard":"type ModelLoadedState = { loaded: true; modelName: string } | { loaded: false };\nconst canTranscribe = (s: ModelLoadedState): s is { loaded: true; modelName: string } => s.loaded;","tryCatchPattern":"try {\n  await invoke('transcribe_audio', { audioData, language });\n} catch (e) {\n  if (String(e).includes('No model loaded')) {\n    await invoke('load_whisper_model', { modelName });\n    await invoke('transcribe_audio', { audioData, language }); // retry once loaded\n  } else { throw e; }\n}","preventionTips":["Auto-load the persisted last-used model at app startup and await it before enabling Record","Bind the Record button's disabled state to the model-loaded event from the Rust side","Remember models must be re-loaded every process start; on-disk presence is not enough"],"tags":["whisper","transcription","state-management","rust","tauri"],"backgroundTag":"use-before-initialization","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}