Zackriya-Solutions/meetily · error

Whisper engine not initialized

Error message

Whisper engine not initialized

What it means

get_or_init_whisper only reads the process-global WHISPER_ENGINE static (a Mutex<Option<Arc<WhisperEngine>>>); it never constructs an engine. When the static is None — no whisper engine was created in this app session because the initialization command never ran or failed earlier — imports on the whisper path fail here. Despite the 'get_or_init' name, there is no lazy initialization.

Source

Thrown at frontend/src-tauri/src/audio/import.rs:792

            if needs_load {
                info!(
                    "Loading Whisper model '{}' (current: {:?})",
                    target_model, current_model
                );

                if let Err(e) = e.discover_models().await {
                    warn!("Model discovery error (continuing): {}", e);
                }

                e.load_model(&target_model)
                    .await
                    .map_err(|e| anyhow!("Failed to load model '{}': {}", target_model, e))?;
            }

            Ok(e)
        }
        None => Err(anyhow!("Whisper engine not initialized")),
    }
}

/// Get or initialize the Parakeet engine
async fn get_or_init_parakeet<R: Runtime>(
    app: &AppHandle<R>,
    requested_model: Option<&str>,
) -> Result<Arc<ParakeetEngine>> {
    use crate::parakeet_engine::commands::PARAKEET_ENGINE;

    let engine = {
        let guard = PARAKEET_ENGINE.lock().unwrap_or_else(|e| e.into_inner());
        guard.as_ref().cloned()
    };

    match engine {
        Some(e) => {
            let target_model = match requested_model {

View on GitHub (pinned to 0281737d87)

Solutions

  1. Trigger whisper engine initialization before import — run the same init/load path the model settings page uses, or invoke its Tauri command once at app start
  2. Check logs since launch: an earlier engine-creation failure explains the None global
  3. Make get_or_init_whisper actually lazy: construct and store the engine when None instead of erroring
  4. In tests, populate WHISPER_ENGINE before calling the import command

Example fix

// before — None is a dead end
match engine {
    Some(e) => Ok(e),
    None => Err(anyhow!("Whisper engine not initialized")),
}

// after — initialize on miss
let engine = match engine {
    Some(e) => e,
    None => {
        let e = Arc::new(WhisperEngine::new());
        *WHISPER_ENGINE.lock().unwrap_or_else(|x| x.into_inner()) = Some(e.clone());
        e
    }
};
Defensive patterns

Strategy: validation

Validate before calling

// ensure the engine exists before starting an import
use crate::whisper_engine::commands::WHISPER_ENGINE;
let ready = WHISPER_ENGINE
    .lock()
    .map(|g| g.is_some())
    .unwrap_or(false);
if !ready { initialize_whisper_engine(&app).await?; }

Type guard

fn whisper_engine_ready() -> bool {
    use crate::whisper_engine::commands::WHISPER_ENGINE;
    WHISPER_ENGINE.lock().map(|g| g.is_some()).unwrap_or(false)
}

Try / catch

Treat this error as unretryable at the call site: catch it, initialize the engine via the app's init path, then restart the import from the beginning — importing again is safe because cancellation cleaned the previous meeting folder.

Prevention

When it happens

Trigger: Starting an import (provider != 'parakeet', >0 VAD segments) in a fresh app session before any whisper engine initialization has happened; a prior engine-creation failure left the global unset; the init code path removed or reordered by a refactor.

Common situations: Cold start followed directly by import without visiting settings or loading a model first; automated tests invoking the import command without engine setup; nightly build where the init command was renamed.

Related errors


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