{"record":{"id":"1c49d930b62b8dfb","repo":"Zackriya-Solutions/meetily","slug":"download-timeout-for-no-data-received-for-30-seconds","errorCode":null,"errorMessage":"Download timeout for {}: no data received for 30 seconds","messagePattern":"Download timeout for (.+?): no data received for 30 seconds","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs","lineNumber":1013,"sourceCode":"            let mut stream = response.bytes_stream();\n\n            loop {\n                let next_chunk = tokio::select! {\n                    biased;\n                    _ = active_download.cancellation.cancelled() => {\n                        writer.flush().await.map_err(|error| {\n                            anyhow!(\"Failed to preserve {} during cancellation: {}\", artifact.filename, error)\n                        })?;\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","sourceCodeStart":995,"sourceCodeEnd":1031,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/a2cb62e827da7ef59f65064c97233efb2313878e/frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs#L995-L1031","documentation":"Raised when a Parakeet artifact download stream yields no data for 30 seconds: `timeout(Duration::from_secs(30), stream.next())` returns `Err(_)` (elapsed). The engine first flushes the BufWriter to persist received bytes for HTTP-Range resume, then returns this timeout error describing the stalled filename. This is the expected user-facing outcome of a stalled transfer when the partial file could still be preserved.","triggerScenarios":"The reqwest `bytes_stream()` for the artifact receives zero chunks within 30 s during `download_models`: server stops responding mid-body, connection silently dropped (sleep/VPN/wifi loss), proxy keeps the socket open but sends nothing, or CDN throttles to a stall. Unlike error 42, this is returned when the preservation flush succeeds.","commonSituations":"Slow or intermittent internet during a multi-hundred-MB model download; laptop sleep/resume breaking the TCP connection without erroring the stream; corporate firewall idle-timeout on long transfers; Hugging Face CDN hiccup.","solutions":["Retry the download — the partial file is preserved and the next attempt resumes from the received byte offset with a Range request.","Check the network path: disable idle-timeout proxies/VPN split tunneling, keep the machine awake during download.","If your connection is reliably slow-but-alive (long TTFB between chunks), the 30 s window is aggressive — increase it or add automatic retry around the engine call.","Verify the artifact URL/CDN is healthy; if a mirror is down, switch network or wait and retry.","For fully offline setups, pre-place the model files manually in the models directory so no download is needed."],"exampleFix":"// caller: make stalled downloads self-healing instead of surfacing the error\nlet result = loop {\n    match engine.download_models(&artifacts, &token).await {\n        Err(e) if e.to_string().contains(\"no data received for 30 seconds\") && !token.is_cancelled() => {\n            warn!(\"download stalled, resuming: {e}\");\n            continue; // resumes from preserved partial bytes\n        }\n        other => break other,\n    }\n};","handlingStrategy":"retry","validationCode":"// check connectivity + server liveness before kicking off a multi-GB download\nif reqwest::get(\"https://huggingface.co\").await.is_err() {\n    return Err(\"no network access; defer model download\".into());\n}\n// ensure room for the resume append\nif free_space(&models_dir)? < artifact.exact_bytes {\n    return Err(\"not enough disk space for artifact\".into());\n}","typeGuard":null,"tryCatchPattern":"match engine.download_models(&artifacts, &token).await {\n    Err(e) if e.to_string().contains(\"no data received for 30 seconds\") => {\n        // safe to retry: partial file preserved, next call resumes via Range\n        engine.download_models(&artifacts, &token).await?;\n    }\n    other => other?,\n}","preventionTips":["Retry automatically on this timeout — resume logic makes retries cheap and idempotent","Prevent laptop sleep mid-download (caffeinate / power settings) so TCP connections survive","Use a stable connection for multi-hundred-MB model downloads; avoid captive-portal wifi","Check the CDN URL is reachable (HEAD request) before starting","For offline machines, install model files manually into the models directory"],"tags":["network","timeout","stall","model-download","http"],"backgroundTag":"request-timeout","analyzedSha":"a2cb62e827da7ef59f65064c97233efb2313878e","analyzedAt":"2026-09-12T11:12:14.152Z","contentChangedAt":"2026-09-12T11:12:14.152Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}