{"record":{"id":"87f62a0d2665f693","repo":"Zackriya-Solutions/meetily","slug":"failed-to-preserve-after-stream-error","errorCode":null,"errorMessage":"Failed to preserve {} after stream error: {}","messagePattern":"Failed to preserve (.+?) after stream error: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs","lineNumber":1021,"sourceCode":"                        })?;\n                        return Err(DownloadCancelled.into());\n                    }\n                    chunk = timeout(Duration::from_secs(30), stream.next()) => chunk,\n                };\n                let chunk = match next_chunk {\n                    Err(_) => {\n                        writer.flush().await.map_err(|error| {\n                            anyhow!(\"Failed to preserve {} after timeout: {}\", artifact.filename, error)\n                        })?;\n                        return Err(anyhow!(\n                            \"Download timeout for {}: no data received for 30 seconds\",\n                            artifact.filename\n                        ));\n                    }\n                    Ok(None) => break,\n                    Ok(Some(Err(error))) => {\n                        writer.flush().await.map_err(|flush_error| {\n                            anyhow!(\n                                \"Failed to preserve {} after stream error: {}\",\n                                artifact.filename,\n                                flush_error\n                            )\n                        })?;\n                        return Err(anyhow!(\"Download stream failed for {}: {}\", artifact.filename, error));\n                    }\n                    Ok(Some(Ok(chunk))) => chunk,\n                };\n\n                let chunk_bytes = chunk.len() as u64;\n                let next_artifact_bytes = artifact_bytes\n                    .checked_add(chunk_bytes)\n                    .ok_or_else(|| anyhow!(\"{} size overflow\", artifact.filename))?;\n                if next_artifact_bytes > artifact.exact_bytes {\n                    writer.flush().await.map_err(|error| {\n                        anyhow!(\"Failed to preserve {} after overlong response: {}\", artifact.filename, error)\n                    })?;","sourceCodeStart":1003,"sourceCodeEnd":1039,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/a2cb62e827da7ef59f65064c97233efb2313878e/frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs#L1003-L1039","documentation":"Raised when the artifact's HTTP byte stream itself yields an error (`Ok(Some(Err(error)))` from `bytes_stream()`), e.g. a connection reset or body read failure mid-download. The engine flushes the BufWriter to keep partial bytes resumable; if that flush fails with `flush_error`, this message wrapping the flush error is produced (the original stream error is then lost).","triggerScenarios":"The reqwest response body errors mid-transfer: connection reset by peer, TLS handshake/renegotiation failure, server closed the connection early (truncated response), reqwest timeout on the connection, DNS/network flaps during the transfer — and the post-error flush to the local file then fails too.","commonSituations":"Router/wifi drops mid-download resetting the TCP connection; server (HF CDN) closes the body early under load; corporate proxy TLS-intercepts and kills long transfers; disk becomes full or the partial file gets locked right as the stream fails, so preservation also fails.","solutions":["Retry the download — the engine appends from the preserved partial file via Range resume, so a mid-stream reset only costs the lost interval.","Diagnose the stream cause: run with `RUST_LOG=debug` and check reqwest/hyper logs for `connection reset`, `broken pipe`, or TLS errors; fix that layer (proxy, MTU, VPN).","Free disk space / verify the models directory is writable — this exact message only appears when the post-error flush fails, almost always storage-side (disk full, locked file, unplugged drive).","Exclude the models directory from antivirus/indexing to prevent the partial file from being locked during the flush.","If the CDN habitually truncates, wrap the engine call in a retry loop; on repeated truncation at the same offset, delete the partial file so the next attempt starts clean."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight connectivity + TLS sanity to the artifact host\nlet resp = reqwest::Client::new().head(&file_url)\n    .timeout(Duration::from_secs(10)).send().await\n    .map_err(|e| format!(\"cannot reach artifact host: {e}\"))?;\nif !resp.status().is_success() {\n    return Err(format!(\"artifact host returned {}\", resp.status()));\n}","typeGuard":null,"tryCatchPattern":"let mut failures = 0;\nloop {\n    match engine.download_models(&artifacts, &token).await {\n        Err(e) if e.to_string().contains(\"after stream error\") && failures < 3 => {\n            failures += 1;\n            tokio::time::sleep(Duration::from_secs(2u64.pow(failures))).await;\n        }\n        Err(e) if e.to_string().contains(\"after stream error\") => {\n            // repeated truncation: drop the suspect partial file and start clean\n            let _ = tokio::fs::remove_file(&partial_path).await;\n            engine.download_models(&artifacts, &token).await?;\n            break;\n        }\n        other => break other,\n    }\n}","preventionTips":["Retry mid-stream resets — the partial file is preserved and the next attempt resumes via Range","Fix chronic reset sources: flaky wifi, MTU issues, TLS-intercepting corporate proxies","Keep the models dir writable with free space so the post-error flush never fails","Check hyper/reqwest debug logs to distinguish connection-reset vs TLS vs early-EOF causes","Delete and re-download the partial file if failures always occur at the same byte offset"],"tags":["network","stream","flush","model-download","http"],"backgroundTag":"http-request-failed","analyzedSha":"a2cb62e827da7ef59f65064c97233efb2313878e","analyzedAt":"2026-09-12T11:12:14.152Z","contentChangedAt":"2026-09-12T11:12:14.152Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}