{"record":{"id":"15d54d5286153c8c","repo":"Zackriya-Solutions/meetily","slug":"download-timeout-no-data-received-for-30-seconds-15d54d","errorCode":null,"errorMessage":"Download timeout - No data received for 30 seconds","messagePattern":"Download timeout - No data received for 30 seconds","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src-tauri/src/summary/summary_engine/model_manager.rs","lineNumber":608,"sourceCode":"            let chunk = match next_result {\n                // Timeout - no data received for 30 seconds\n                Err(_) => {\n                    log::warn!(\"Download timeout for {}: no data received for 30 seconds\", model_name);\n                    let _ = writer.flush().await;\n\n                    // Cleanup: Remove from active downloads\n                    let mut active = self.active_downloads.write().await;\n                    active.remove(model_name);\n\n                    // Set model status to Error (NOT NotDownloaded) so UI can show retry button\n                    {\n                        let mut models = self.available_models.write().await;\n                        if let Some(model_info) = models.get_mut(model_name) {\n                            model_info.status = ModelStatus::Error(\"Download timeout - No data received for 30 seconds\".to_string());\n                        }\n                    }\n\n                    return Err(anyhow!(\"Download timeout - No data received for 30 seconds\"));\n                },\n                // Stream ended\n                Ok(None) => break,\n                // Got chunk result\n                Ok(Some(chunk_result)) => {\n                    match chunk_result {\n                        Ok(c) => c,\n                        // Detect error type for better user feedback\n                        Err(e) => {\n                            log::error!(\"Download error for {}: {:?}\", model_name, e);\n                            let _ = writer.flush().await;\n\n                            // Cleanup: Remove from active downloads\n                            let mut active = self.active_downloads.write().await;\n                            active.remove(model_name);\n\n                            // Categorize error for user-friendly message\n                            let error_msg = if e.is_timeout() {","sourceCodeStart":590,"sourceCodeEnd":626,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/summary/summary_engine/model_manager.rs#L590-L626","documentation":"The per-chunk 30-second timeout expired with zero bytes from the stream: the connection is open but stalled. Unlike the parakeet variant, model status is set to Error (with this message) so the UI can show a retry button; the partial file remains and the next attempt resumes via the Range header.","triggerScenarios":"CDN stalls the body mid-transfer; proxy/captive portal accepting the connection but never streaming; VPN rekey or Wi-Fi roam freezing the socket; server throttling that pauses after headers.","commonSituations":"Corporate proxies rate-limiting large GGUF downloads; network switch mid-download; slow origin after long pauses.","solutions":["Retry the download — resume continues from the preserved partial file","If it stalls at the same offset repeatedly, delete the partial file and retry fresh","Bypass or diagnose interfering proxies/VPNs (curl the same URL)","For persistently slow links, increase the 30 s chunk timeout rather than retrying in a loop"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"let mut attempt = 0;\nloop {\n    match manager.download_model_detailed(name, cb).await {\n        Err(e) if e.to_string().contains(\"Download timeout\") && attempt < 3 => {\n            attempt += 1;\n            tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await; // resumes from partial\n        }\n        other => break other,\n    }\n}","preventionTips":["Retry with backoff and rely on Range-based resume instead of restarting","Delete the partial file if stalls repeat at the same byte offset (corrupt resume state)","Expose model status Error in the UI with a retry action, matching the manager's intent"],"tags":["network","timeout","download","rust"],"backgroundTag":"network-read-timeout","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}