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

Failed to preserve {} after timeout: {}

Error message

Failed to preserve {} after timeout: {}

What it means

Raised when the download stream stalls and `tokio::time::timeout(Duration::from_secs(30), stream.next())` elapses with no chunk arriving. The engine flushes the buffered writer to preserve the partial file for a later range-resume, then throws this error. If that emergency flush fails, this error message is produced instead of the timeout message.

Source

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

            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| {
                            anyhow!(
                                "Failed to preserve {} after stream error: {}",
                                artifact.filename,
                                flush_error
                            )
                        })?;
                        return Err(anyhow!("Download stream failed for {}: {}", artifact.filename, error));
                    }
                    Ok(Some(Ok(chunk))) => chunk,

View on GitHub (pinned to a2cb62e827)

Solutions

  1. Simply retry the download — the engine preserves partial bytes specifically so the next attempt resumes via HTTP Range; transient stalls are expected.
  2. Check network stability (VPN, proxy, wifi) and disable throttling proxies for the model host.
  3. Free disk space / fix storage access — this exact message only appears when the stall-timeout flush also failed, typically because the disk filled during the stall.
  4. If stalls are chronic, increase the 30-second `timeout` window or add automatic retry-with-backoff around the download loop.
  5. Verify the artifacts' URL host is reachable (curl the file URL with a Range header) to rule out server-side issues.

Example fix

// before: single attempt, one 30s stall kills the download
return Err(anyhow!("Failed to preserve {} after timeout: {}", artifact.filename, error));

// after: caller-side retry loop; partial file makes the next attempt resume
for attempt in 1..=3 {
    match engine.download_models(&artifacts, &cancel).await {
        Ok(()) => break,
        Err(e) if attempt < 3 && !cancel.is_cancelled() => {
            log::warn!("model download stalled ({}), retry {}/3", e, attempt + 1);
            tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await;
        }
        Err(e) => return Err(e),
    }
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: is the artifact host responsive at all?
let probe = reqwest::Client::new()
    .head(&file_url)
    .timeout(Duration::from_secs(10))
    .send().await;
if !matches!(&probe, Ok(r) if r.status().is_success() || r.status().as_u16() == 206) {
    return Err("artifact host unreachable or throttling; fix network before download".into());
}

Try / catch

let mut attempt = 0;
loop {
    match engine.download_models(&artifacts, &token).await {
        Err(e) if e.to_string().contains("after timeout") && attempt < 3 => {
            attempt += 1;
            tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await;
        }
        other => break other,
    }
}

Prevention

When it happens

Trigger: The HTTP body stream for a Parakeet artifact produces no chunk within 30 seconds: the CDN/HF mirror stalls mid-transfer, the network drops without an RST (VPN/sleep/wifi change), a proxy silently holds the connection, or the server stops sending after partial content. Only fires when the subsequent flush also errors (otherwise the "Download timeout" error 43 is returned).

Common situations: Laptop suspends mid-download and the connection is dead on resume; corporate proxy drops long-running large-file transfers; flaky wifi drops packets during a multi-GB model download; the Hugging Face CDN throttles or stalls a slow connection.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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