Zackriya-Solutions/meetily · error

Failed to open file for append: {}

Error message

Failed to open file for append: {}

What it means

On the resume path (server returned 206), OpenOptions with write+append failed on the existing partial file. Something invalidated the file between the size probe and the open: it was deleted, its permissions changed, or another process locked it.

Source

Thrown at frontend/src-tauri/src/summary/summary_engine/model_manager.rs:524

                log::warn!("Server doesn't support resume, starting fresh download");
            }
            (response.content_length().unwrap_or(0), false)
        } else {
            let mut active = self.active_downloads.write().await;
            active.remove(model_name);
            return Err(anyhow!("Download failed with status: {}", response.status()));
        };

        log::info!("Total size: {} MB", total_size / (1024 * 1024));

        // Open file for append if resuming, or create new
        let file = if resuming {
            OpenOptions::new()
                .write(true)
                .append(true)
                .open(&file_path)
                .await
                .map_err(|e| anyhow!("Failed to open file for append: {}", e))?
        } else {
            fs::File::create(&file_path)
                .await
                .map_err(|e| anyhow!("Failed to create file: {}", e))?
        };

        // Use 8MB buffer to reduce disk I/O syscalls (major performance improvement)
        let mut writer = BufWriter::with_capacity(8 * 1024 * 1024, file);

        let mut downloaded: u64 = if resuming { existing_size } else { 0 };

        // Emit initial progress (showing resumed position if applicable)
        if let Some(ref callback) = progress_callback {
            callback(DownloadProgress::new(downloaded, total_size, 0.0));
        }
        log::info!(
            "Starting at {:.1} MB / {:.1} MB",
            downloaded as f64 / (1024.0 * 1024.0),

View on GitHub (pinned to 0281737d87)

Solutions

  1. If the partial file is gone or corrupt, delete any remnants and retry without a Range header (fresh download)
  2. Close other app instances that may hold the file, then retry
  3. Fix directory permissions and exclude the models directory from AV/sync tools
  4. Retry after remounting the volume that hosts the models directory
Defensive patterns

Strategy: fallback

Validate before calling

// Verify the partial file is still openable before requesting a resume
if existing_size > 0 {
    match tokio::fs::OpenOptions::new().append(true).open(&file_path).await {
        Ok(_) => { /* safe to resume */ }
        Err(_) => { tokio::fs::remove_file(&file_path).await.ok(); /* fall back to fresh */ }
    }
}

Try / catch

match download_result {
    Err(e) if e.to_string().starts_with("Failed to open file for append") => {
        tokio::fs::remove_file(&file_path).await.ok();
        manager.download_model_detailed(name, cb).await // fresh download, no Range
    }
    other => other,
}

Prevention

When it happens

Trigger: Partial file deleted by a cleaner/sync tool after the Range request succeeded; read-only models directory; Windows file lock from antivirus or a second app instance; models directory on unmounted external storage.

Common situations: Two instances of the app downloading the same model; AV scanning the partial .gguf while it is reopened; utilities that remove 'unfinished' downloads.

Related errors


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