{"record":{"id":"1afb3731c900b2ff","repo":"cjpais/Handy","slug":"no-response-within-s-from","errorCode":null,"errorMessage":"no response within {}s from {}","messagePattern":"no response within (.+?)s from (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/managers/model/download.rs","lineNumber":228,"sourceCode":"        if resume_from > 0 {\n            info!(\n                \"Resuming download of {} from byte {}\",\n                model_id, resume_from\n            );\n        } else {\n            info!(\"Starting fresh download of {} from {}\", model_id, url);\n        }\n\n        let client = reqwest::Client::builder()\n            .connect_timeout(HTTP_CONNECT_TIMEOUT)\n            .build()?;\n        let mut request = client.get(url);\n        if resume_from > 0 {\n            request = request.header(\"Range\", format!(\"bytes={}-\", resume_from));\n        }\n        let response = tokio::select! {\n            r = tokio::time::timeout(DOWNLOAD_STALL_TIMEOUT, request.send()) => r\n                .map_err(|_| anyhow::anyhow!(\n                    \"no response within {}s from {}\",\n                    DOWNLOAD_STALL_TIMEOUT.as_secs(), url\n                ))??,\n            _ = cancel_token.cancelled() => return Ok(HttpDownloadOutcome::Cancelled),\n        };\n\n        // 416 to our Range request means its start is at or past the object's\n        // end. With a catalog size in hand that can only mean the server's\n        // object is *smaller* than expected (a full-size partial never issues\n        // a request — handled above), and with no hash there is no trusted\n        // signal to bless the partial: both restart clean. Only a hash can\n        // genuinely finish a partial here. Without a Range in flight a 416 is\n        // just a broken server, which the generic status check below rejects.\n        if resume_from > 0 && response.status() == reqwest::StatusCode::RANGE_NOT_SATISFIABLE {\n            if expected_size.is_some() || expected_sha256.is_none() {\n                let _ = fs::remove_file(partial_path);\n                return Err(anyhow::anyhow!(\n                    \"server object ends before the expected size (HTTP 416)\"","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/cjpais/Handy/blob/c89b7bf38974ad317177389f5bfe28236f0d64e3/src-tauri/src/managers/model/download.rs#L210-L246","documentation":"Raised when the HTTP request to start (or resume) a model download produces no response within DOWNLOAD_STALL_TIMEOUT (60 s, racing a 15 s connect timeout). The tokio::select! also races the cancel token, so this error specifically means: not cancelled, but the server never finished sending response headers in time. Any partial file on disk is kept, so a subsequent download call resumes instead of restarting.","triggerScenarios":"request.send() exceeds 60 s: unreachable/black-holing host (packets dropped after connect), proxy that accepts the connection but never answers, server headers delayed behind a slow backend, or DNS+connect to a dead mirror exceeding the window.","commonSituations":"Firewalled networks blocking blob/HF hosts; VPN split-tunnel dropping traffic to CDNs; overloaded mirrors; captive portals that hold connections open; flaky mobile tethers.","solutions":["Retry the download — the resumable downloader continues from the kept partial where one exists.","Check basic reachability of the URL (curl -I <url>) from the same machine/network.","Disable/adjust VPN or proxy if it intercepts the model hosts.","Switch to a different mirror/URL for the model if the primary host consistently times out.","If on restricted networks (corporate/school), allow-list the download domains."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Cheap pre-flight before a long download\nlet client = reqwest::Client::builder().timeout(Duration::from_secs(20)).build()?;\nlet resp = client.head(url).send().await?;\nif !resp.status().is_success() {\n    anyhow::bail!(\"download source unhealthy: HTTP {}\", resp.status());\n}","typeGuard":null,"tryCatchPattern":"match manager.download_model(model_id, None).await {\n    Ok(_) => Ok(()),\n    Err(e) if e.to_string().contains(\"no response within\") => {\n        // partial is preserved; retry resumes instead of restarting\n        manager.download_model(model_id, None).await\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Pre-flight the URL (HEAD request) before offering the download in the UI.","Keep retry loops resumable — never delete the partial on timeout.","Keep model hosts reachable: allow-list them on restricted networks.","Avoid VPN/proxy paths that black-hole large transfers."],"tags":["download","timeout","network","reqwest","http"],"backgroundTag":"request-timeout","analyzedSha":"c89b7bf38974ad317177389f5bfe28236f0d64e3","analyzedAt":"2026-08-17T10:29:55.597Z","contentChangedAt":"2026-08-17T10:29:55.597Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}