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

Failed to create file: {}

Error message

Failed to create file: {}

What it means

tokio fs::File::create on models_dir/ggml-<model>.bin failed before any bytes were written; the OS error is appended. Common errnos: PermissionDenied (locked or read-only), NotFound (parent vanished), ENOSPC (disk full), or Windows sharing violations on a leftover partial file.

Source

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

            .map_err(|e| anyhow!("Failed to start download: {}", e))?;
        
        log::info!("Received response with status: {}", response.status());
        if !response.status().is_success() {
            // Remove from active downloads on error
            let mut active = self.active_downloads.write().await;
            active.remove(model_name);
            return Err(anyhow!("Download failed with status: {}", response.status()));
        }
        
        let total_size = response.content_length().unwrap_or(0);
        log::info!("Response successful, content length: {} bytes ({:.1} MB)", total_size, total_size as f64 / (1024.0 * 1024.0));
        
        if total_size == 0 {
            log::warn!("Content length is 0 or unknown - download may not show accurate progress");
        }
        
        let mut file = fs::File::create(&file_path).await
            .map_err(|e| anyhow!("Failed to create file: {}", e))?;
        
        log::info!("File created successfully at: {}", file_path.display());
        
        // Stream download with real progress reporting
        log::info!("Starting streaming download...");
        log::info!("Expected size: {:.1} MB", total_size as f64 / (1024.0 * 1024.0));

        use futures_util::StreamExt;
        let mut stream = response.bytes_stream();
        let mut downloaded = 0u64;
        let mut last_progress_report = 0u8;
        let mut last_report_time = std::time::Instant::now();

        // Emit initial 0% progress immediately
        if let Some(ref callback) = progress_callback {
            callback(0);
        }

View on GitHub (pinned to 0281737d87)

Solutions

  1. Free disk space to at least the model's expected size (tiny ~75MB, base ~142MB, large-v3 ~3GB) plus margin
  2. Delete the stale partial ggml-<model>.bin manually and retry
  3. Fix write permissions on the models directory; ensure only one app instance runs
Defensive patterns

Strategy: validation

Validate before calling

// Rust: check free space against expected size before creating the file
const EXPECTED_MIN: u64 = 75 * 1024 * 1024; // per-model table in production
let free = fs2::available_space(&self.models_dir)?;
if free < EXPECTED_MIN {
    return Err(anyhow!("Insufficient disk space: {} bytes free", free));
}

Try / catch

try {
  await invoke('download_model', { modelName });
} catch (e) {
  const msg = String(e);
  if (msg.includes('Failed to create file')) {
    if (msg.includes('denied')) showPermissionHelp();
    else showDiskSpaceHelp();
  } else { throw e; }
}

Prevention

When it happens

Trigger: A partial ggml file from an interrupted earlier download is held open by AV or another instance (Windows sharing violation); models directory permissions changed; disk already full before the ~150MB–3GB write begins.

Common situations: Disk filled by a previous failed large-v3 download; antivirus scanning the stale partial .bin; models dir on an external drive that re-mounted read-only.

Related errors


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