Zackriya-Solutions/meetily · error · anyhow::Error

No model loaded. Please load a model first.

Error message

No model loaded. Please load a model first.

What it means

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.

Source

Thrown at frontend/src-tauri/src/whisper_engine/whisper_engine.rs:519

            return 0.0;
        }

        let mut word_counts = HashMap::new();
        for word in &words {
            *word_counts.entry(word.to_lowercase()).or_insert(0) += 1;
        }

        let total_words = words.len() as f32;
        let repeated_words: usize = word_counts.values().map(|&count| if count > 1 { count - 1 } else { 0 }).sum();

        repeated_words as f32 / total_words
    }
    
    /// Transcribe audio with streaming support for partial results and adaptive quality
    pub async fn transcribe_audio_with_confidence(&self, audio_data: Vec<f32>, language: Option<String>) -> Result<(String, f32, bool)> {
        let ctx_lock = self.current_context.read().await;
        let ctx = ctx_lock.as_ref()
            .ok_or_else(|| anyhow!("No model loaded. Please load a model first."))?;

        // Get adaptive configuration based on hardware
        let hardware_profile = crate::audio::HardwareProfile::detect();
        let adaptive_config = hardware_profile.get_whisper_config();

        // ADAPTIVE parameters - optimized for current hardware
        let mut params = FullParams::new(SamplingStrategy::BeamSearch {
            beam_size: adaptive_config.beam_size as i32,
            patience: 1.0
        });

        // Configure with adaptive settings
        // If language is "auto" or None, use automatic language detection (pass None)
        // If language is "auto-translate", enable translation to English
        // Otherwise, use the specified language code
        let (language_code, should_translate) = match language.as_deref() {
            Some("auto") | None => (None, false),
            Some("auto-translate") => (None, true),

View on GitHub (pinned to 0281737d87)

Solutions

  1. Await a successful load_model(model_name) before starting recording or feeding audio chunks
  2. Gate the Record button on the model-loaded state event instead of assuming a model is present
  3. Persist the last-used model name and load it automatically at app startup, blocking transcription until it completes

Example fix

// before
startRecording();                       // audio arrives, engine has no context
await invoke('load_whisper_model', { modelName });

// after
await invoke('load_whisper_model', { modelName });
startRecording();
Defensive patterns

Strategy: validation

Validate before calling

// Frontend: only start recording when a model is loaded
const loaded = await invoke<boolean>('is_whisper_model_loaded'); // or track via state events
if (!loaded) {
  await invoke('load_whisper_model', { modelName: lastUsedModel });
}
await invoke('start_recording', { /* ... */ });

Type guard

type ModelLoadedState = { loaded: true; modelName: string } | { loaded: false };
const canTranscribe = (s: ModelLoadedState): s is { loaded: true; modelName: string } => s.loaded;

Try / catch

try {
  await invoke('transcribe_audio', { audioData, language });
} catch (e) {
  if (String(e).includes('No model loaded')) {
    await invoke('load_whisper_model', { modelName });
    await invoke('transcribe_audio', { audioData, language }); // retry once loaded
  } else { throw e; }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/b0ee8aa8a7de5c9f. Report an issue: GitHub.