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

Failed to read downloaded model file metadata: {}

Error message

Failed to read downloaded model file metadata: {}

What it means

During post-download validation, finish_download calls fs::metadata(file_path) on the freshly downloaded model file. If that metadata read fails (std::io::Error), the download is treated as failed and this anyhow error wraps the underlying OS error. It means the app downloaded bytes but cannot stat the resulting file, so the size sanity check cannot run. The partial file is then deleted and the model status is reset to Missing.

Source

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

        if result.is_ok() && !active_download.cancellation.is_cancelled() {
            result = self.validate_model_file(file_path).await;

            if result.is_ok() {
                let expected_min_size = WHISPER_MODEL_CATALOG
                    .iter()
                    .find(|model| model.0 == model_name)
                    .map(|model| ((model.2 as f64 * 0.9) as u64) * 1024 * 1024);

                result = match expected_min_size {
                    Some(expected_min_size) => match fs::metadata(file_path).await {
                        Ok(metadata) if metadata.len() >= expected_min_size => Ok(()),
                        Ok(metadata) => Err(anyhow!(
                            "Downloaded model file is too small: {} bytes (expected at least {} bytes)",
                            metadata.len(),
                            expected_min_size
                        )),
                        Err(e) => Err(anyhow!(
                            "Failed to read downloaded model file metadata: {}",
                            e
                        )),
                    },
                    None => Err(anyhow!(
                        "Unsupported model for download validation: {}",
                        model_name
                    )),
                };
            }
        }

        if result.is_err() && !active_download.cancellation.is_cancelled() && file_path.exists() {
            if let Err(e) = fs::remove_file(file_path).await {
                log::warn!("Failed to clean up failed download file: {}", e);
            } else {
                log::info!("Cleaned up failed download file: {}", file_path.display());
            }

View on GitHub (pinned to a2cb62e827)

Solutions

  1. Check the models directory still exists and is on a local, mounted, writable volume before downloading (UI shows the path in model settings).
  2. Exclude the Meetily models directory from antivirus/EDR real-time scanning or quarantine of large .bin files.
  3. Verify nothing else (another app instance, cloud-sync like Dropbox/OneDrive) is managing or deleting files in the models folder.
  4. Retry the download — transient stat failures (racing cleanup, brief unmount) usually succeed on a second attempt.
  5. If reproducible, inspect the wrapped io::Error in the message ('{}' suffix) for the concrete OS reason (NOENT, PERMISSION_DENIED, etc.) and fix that root cause.

Example fix

// before: stat may race with concurrent cleanup/delete
let result = match fs::metadata(file_path).await {
    Ok(m) if m.len() >= expected_min_size => Ok(()),
    Ok(m) => Err(anyhow!("too small: {}", m.len())),
    Err(e) => Err(anyhow!("Failed to read downloaded model file metadata: {}", e)),
};
// after: retry once and tolerate a racing delete by falling back to read-based size
let result = match fs::metadata(file_path).await.or_else(|_| fs::metadata(file_path).await) {
    Ok(m) if m.len() >= expected_min_size => Ok(()),
    Ok(m) => Err(anyhow!("Downloaded model file is too small: {} bytes (expected at least {} bytes)", m.len(), expected_min_size)),
    Err(e) if e.kind() == std::io::ErrorKind::NotFound =>
        Err(anyhow!("Downloaded model file disappeared before validation: {}", file_path.display())),
    Err(e) => Err(anyhow!("Failed to read downloaded model file metadata: {}", e)),
};
Defensive patterns

Strategy: try-catch

Validate before calling

let path = models_dir.join(format!("ggml-{}.bin", model_name));
if !models_dir.exists() {
    return Err("models directory is missing or unmounted");
}
if let Err(e) = tokio::fs::metadata(&path).await {
    eprintln!("pre-flight stat of {} failed: {}", path.display(), e);
}

Type guard

fn is_stat_likely_ok(path: &std::path::Path) -> bool {
    path.parent().map(|p| p.is_dir()).unwrap_or(false)
        && path
            .file_name()
            .and_then(|n| n.to_str())
            .map(|n| !n.is_empty() && n.len() < 255)
            .unwrap_or(false)
}

Try / catch

match download_result {
    Err(e) if e.to_string().contains("Failed to read downloaded model file metadata") => {
        // transient stat failure: verify no AV/cloud-sync interference, then retry once
        cleanup_partial_file(&path);
        retry_download(model_name, 1).await
    }
    Err(e) => Err(e),
    Ok(()) => Ok(()),
}

Prevention

When it happens

Trigger: fs::metadata() on the just-written models_dir/ggml-<name>.bin returns Err — e.g. the file was deleted or moved by another process/cleanup between the last write and validation, the file handle/locking on Windows blocks stat, path-too-long or invalid characters in the models dir, or the volume went offline (unmounted external drive, network share drop).

Common situations: User or antivirus quarantines/deletes the large .bin right as download finishes; models directory points at a removable/network drive that disconnects mid-download; another download/cancel task removes the file concurrently (finish_download deletes failed files); permission or filesystem corruption prevents stat.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@a2cb62e827 (2026-09-12). Data as JSON: /api/errors/ed68d921002a1cde. Report an issue: GitHub.