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

Failed to write chunk to file

Error message

Failed to write chunk to file: {}

What it means

file.write_all(chunk) failed during the streaming loop; the OS error is appended and the partial file stays on disk. The dominant cause is ENOSPC — the disk filled while writing a model file that can range from ~75MB (tiny) to ~3GB (large-v3). Permission or quota changes after the file was opened also produce it.

Solutions

  1. Free disk space of at least the model's full size plus margin and retry the download
  2. Switch to a quantized variant (e.g. large-v3-turbo-q5_0) that is several times smaller
  3. Move the models directory to a volume with more free space
Defensive patterns

Strategy: validation

Validate before calling

// Rust: verify free space exceeds the expected model size before streaming
let expected = expected_model_size(model_name); // e.g. tiny 75MB .. large-v3 3GB
let free = fs2::available_space(&self.models_dir)?;
if free < expected + 100 * 1024 * 1024 {
    return Err(anyhow!("Need {} bytes free, have {}", expected, free));
}

Try / catch

try {
  await invoke('download_model', { modelName });
} catch (e) {
  if (String(e).includes('Failed to write chunk')) {
    alertDiskSpace(modelName); // instruct cleanup, offer smaller variant
  } else { throw e; }
}

Prevention

When it happens

Trigger: Disk reaches capacity partway into a large model write; per-user quota on a networked home directory kicks in; external drive unplugged mid-write.

Common situations: Downloading large-v3 or large-v3-turbo with only a few GB free; managed corporate laptops with disk quotas; models directory on a nearly-full partition.

Related errors


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

Appendix: source

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

        loop {
            let chunk_result = tokio::select! {
                biased;
                _ = active_download.cancellation.cancelled() => return Err(DownloadCancelled.into()),
                chunk_result = stream.next() => chunk_result,
            };

            let Some(chunk_result) = chunk_result else {
                break;
            };

            if active_download.cancellation.is_cancelled() {
                return Err(DownloadCancelled.into());
            }

            let chunk = chunk_result.map_err(|e| anyhow!("Failed to read chunk: {}", e))?;
            file.write_all(&chunk)
                .await
                .map_err(|e| anyhow!("Failed to write chunk to file: {}", e))?;

            downloaded += chunk.len() as u64;
            let progress = if total_size > 0 {
                ((downloaded as f64 / total_size as f64) * 100.0) as u8
            } else {
                0
            };

            let time_since_last_report = last_report_time.elapsed().as_secs();
            if progress >= last_progress_report + 1 || progress == 100 || time_since_last_report >= 2 {
                let mut models = self.available_models.write().await;
                if let Some(model_info) = models.get_mut(model_name) {
                    model_info.status = ModelStatus::Downloading { progress };
                }

                if let Some(ref callback) = progress_callback {
                    callback(progress);
                }

View on GitHub (pinned to a2cb62e827)