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

Failed to load Parakeet model {}: {}

Error message

Failed to load Parakeet model {}: {}

What it means

Thrown by ParakeetEngine::load_model when ParakeetModel::new fails to construct the model from the model directory. ParakeetModel::new builds three ONNX Runtime sessions (encoder-model[.int8].onnx, decoder_joint-model[.int8].onnx, nemo128.onnx) and parses vocab.txt, so the wrapped error can be file I/O, a truncated/invalid ONNX file, an ort Session builder failure (GraphOptimizationLevel::Level3 / CPUExecutionProvider registration), or a malformed vocabulary (missing <blk> token). The first {} is the model name; the second {} is the underlying ParakeetError.

Source

Thrown at frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs:401

            ModelStatus::Available => {
                // Check if this model is already loaded
                if let Some(current_model) = self.current_model_name.read().await.as_ref() {
                    if current_model == model_name {
                        log::info!("Parakeet model {} is already loaded, skipping reload", model_name);
                        return Ok(());
                    }

                    // Unload current model before loading new one
                    log::info!("Unloading current Parakeet model '{}' before loading '{}'", current_model, model_name);
                    self.unload_model().await;
                }

                log::info!("Loading Parakeet model: {}", model_name);

                // Load model based on quantization type
                let quantized = model_info.quantization == QuantizationType::Int8;
                let model = ParakeetModel::new(&model_info.path, quantized)
                    .map_err(|e| anyhow!("Failed to load Parakeet model {}: {}", model_name, e))?;

                // Update current model and model name
                *self.current_model.write().await = Some(model);
                *self.current_model_name.write().await = Some(model_name.to_string());

                log::info!(
                    "Successfully loaded Parakeet model: {} ({})",
                    model_name,
                    if quantized { "Int8 quantized" } else { "FP32" }
                );
                Ok(())
            }
            ModelStatus::Missing => {
                Err(anyhow!("Parakeet model {} is not downloaded", model_name))
            }
            ModelStatus::Downloading { .. } => {
                Err(anyhow!("Parakeet model {} is currently downloading", model_name))
            }

View on GitHub (pinned to 0281737d87)

Solutions

  1. Inspect models_dir/<model-name> and confirm all four required files exist with plausible sizes (v3 int8 encoder ~652 MB; v2 int8 ~652 MB; decoder ~9 MB)
  2. If any file is missing or suspiciously small, call delete_model(model_name) then download_model(model_name, ...) and retry the load
  3. Check disk space and read permissions on the models directory
  4. Run with RUST_LOG=app_lib::parakeet_engine=debug to see which session (encoder/decoder_joint/nemo128) or the vocab failed, then verify vocab.txt integrity

Example fix

// before
engine.load_model("parakeet-tdt-0.6b-v3-int8").await?;

// after - recover by removing the bad copy and re-downloading
let name = "parakeet-tdt-0.6b-v3-int8";
if let Err(e) = engine.load_model(name).await {
    log::warn!("Parakeet load failed ({e}); re-downloading {name}");
    let _ = engine.delete_model(name).await;
    engine.download_model(name, None).await?;
    engine.load_model(name).await?;
}
Defensive patterns

Strategy: fallback

Validate before calling

// Before load: confirm status is Available and all required files exist
let infos = engine.discover_models().await?;
let info = infos.iter().find(|m| m.name == model_name)
    .ok_or_else(|| anyhow!("unknown model"))?;
if !matches!(info.status, ModelStatus::Available) {
    anyhow::bail!("model not loadable yet: {:?}", info.status);
}
for f in ["encoder-model.int8.onnx", "decoder_joint-model.int8.onnx", "nemo128.onnx", "vocab.txt"] {
    let p = &info.path.join(f);
    if !p.is_file() {
        anyhow::bail!("missing {} under {}", f, info.path.display());
    }
}

Type guard

fn is_loadable(info: &ModelInfo) -> bool {
    matches!(info.status, ModelStatus::Available)
}

Try / catch

// On failure, recover by deleting the bad copy and re-downloading once
match engine.load_model(name).await {
    Ok(()) => {}
    Err(e) if e.to_string().contains("Failed to load Parakeet model") => {
        log::warn!("load failed ({e}); rebuilding {name}");
        let _ = engine.delete_model(name).await;
        engine.download_model(name, None).await?;
        engine.load_model(name).await?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling load_model("parakeet-tdt-0.6b-v3-int8") when the model directory exists and status is Available, but one of the required files (encoder-model.int8.onnx, decoder_joint-model.int8.onnx, nemo128.onnx, vocab.txt) is truncated from an interrupted download that escaped clean_incomplete_model_directory, was deleted externally, or is unreadable; also when vocab.txt is malformed (no <blk> line parses) or the ort session builder rejects the graph.

Common situations: Disk filled up mid-download leaving a short .onnx file; user or a cleanup tool deleted files inside ~/Library/Application Support/Meetily/models/<model> (macOS) or %APPDATA%\Meetily\models\<model> (Windows); models folder copied between machines partially; ONNX Runtime version change makes an old downloaded graph unloadable.

Related errors


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