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

Failed to preserve {} during cancellation: {}

Error message

Failed to preserve {} during cancellation: {}

What it means

Raised inside the download loop when the user/UI cancels an active Parakeet model download (`active_download.cancellation.cancelled()` fires). Before returning `DownloadCancelled`, the code attempts one final `writer.flush()` so already-buffered bytes are persisted for later resume; if that flush itself fails on the file handle, this error is thrown instead and masks the cancellation with a flush failure. It is a secondary error on top of an intentional cancellation.

Source

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

            } else {
                fs::OpenOptions::new()
                    .create(true)
                    .truncate(true)
                    .write(true)
                    .open(&file_path)
                    .await
                    .map_err(|error| anyhow!("Failed to replace {}: {}", artifact.filename, error))?
            };
            let mut writer = BufWriter::with_capacity(8 * 1024 * 1024, file);
            use futures_util::StreamExt;
            let mut stream = response.bytes_stream();

            loop {
                let next_chunk = tokio::select! {
                    biased;
                    _ = active_download.cancellation.cancelled() => {
                        writer.flush().await.map_err(|error| {
                            anyhow!("Failed to preserve {} during cancellation: {}", artifact.filename, error)
                        })?;
                        return Err(DownloadCancelled.into());
                    }
                    chunk = timeout(Duration::from_secs(30), stream.next()) => chunk,
                };
                let chunk = match next_chunk {
                    Err(_) => {
                        writer.flush().await.map_err(|error| {
                            anyhow!("Failed to preserve {} after timeout: {}", artifact.filename, error)
                        })?;
                        return Err(anyhow!(
                            "Download timeout for {}: no data received for 30 seconds",
                            artifact.filename
                        ));
                    }
                    Ok(None) => break,
                    Ok(Some(Err(error))) => {
                        writer.flush().await.map_err(|flush_error| {

View on GitHub (pinned to a2cb62e827)

Solutions

  1. Fix the root I/O cause reported after the second `{}` — usually disk-full: free space or point the models directory at a drive with room for the full artifact size.
  2. If the models dir is on removable/network storage, move it to local disk (app data dir) so cancellation flushes reliably.
  3. Check that no other process deleted or locked the partial file during download; exclude the models dir from antivirus scanning.
  4. Retry the download after cleanup — the code is designed to resume from a preserved partial file, so once flush works the retry appends cleanly.
  5. If this error frequently hides real cancellations, consider logging flush failures non-fatally during cancellation so `DownloadCancelled` propagates.
Defensive patterns

Strategy: try-catch

Validate before calling

// before cancelling, confirm the partial file is on healthy storage
let meta = tokio::fs::metadata(&partial_path).await
    .map_err(|e| format!("partial file inaccessible, resume may fail: {e}"))?;
if free_space(&partial_path)? < min_free_bytes {
    return Err("insufficient disk space to preserve partial download".into());
}

Try / catch

match engine.download_models(&artifacts, &token).await {
    Err(e) if e.to_string().contains("during cancellation") => {
        log::warn!("cancellation flush failed; discarding partial: {e}");
        let _ = tokio::fs::remove_file(&partial_path).await; // start clean next time
    }
    Err(DownloadCancelledError) => { /* normal cancel path */ }
    other => other?,
}

Prevention

When it happens

Trigger: The download's CancellationToken is cancelled while the BufWriter still holds up to 8 MB of buffered bytes, and the final flush hits an I/O error: file handle became invalid, disk full, medium removed (USB/network drive unplugged), permission revoked mid-download, or the file was deleted/locked by another process during the download.

Common situations: User closes the app or clicks Cancel while the model is mid-download and the disk is already full from the partial write; the models folder lives on an external/network drive that dropped; antivirus locks the partial file at the moment of cancel; crash of the underlying storage during a large multi-GB model download.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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