{"record":{"id":"257ee1a511b25a8a","repo":"xai-org/grok-build","slug":"gcs-download-stalled-no-data-received-for-chunk","errorCode":null,"errorMessage":"GCS download stalled: no data received for {chunk_timeout:?} while downloading {file}","messagePattern":"GCS download stalled: no data received for (.+?) while downloading (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/agent/session_registry_client.rs","lineNumber":386,"sourceCode":"            anyhow::bail!(\"GCS download failed: {}\", gcs_response.status());\n        }\n        if let Some(parent) = dest.parent() {\n            tokio::fs::create_dir_all(parent).await?;\n        }\n        let mut out = tokio::fs::File::create(dest)\n            .await\n            .context(\"create dest file\")?;\n        let chunk_timeout = std::time::Duration::from_secs(60);\n        loop {\n            match tokio::time::timeout(chunk_timeout, gcs_response.chunk()).await {\n                Ok(Ok(Some(chunk))) => {\n                    tokio::io::AsyncWriteExt::write_all(&mut out, &chunk)\n                        .await\n                        .context(\"write chunk to disk\")?;\n                }\n                Ok(Ok(None)) => break,\n                Ok(Err(e)) => return Err(e).context(\"read GCS chunk\"),\n                Err(_) => anyhow::bail!(\n                    \"GCS download stalled: no data received for {chunk_timeout:?} \\\n                     while downloading {file}\"\n                ),\n            }\n        }\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    // ── UpdateRequest wire shapes ────────────────────────────────────────────\n    //\n    // The writer split relies on two distinct update payloads being sent at\n    // different times:\n    //","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/agent/session_registry_client.rs#L368-L404","documentation":"While streaming the GCS response body to disk, download_file wraps chunk reads in tokio::time::timeout. If no chunk arrives within chunk_timeout, it aborts with this error naming the timeout duration and target file. It prevents a hung connection from blocking the caller forever.","triggerScenarios":"Calling download_file when the GCS connection stalls: the body stream yields nothing within the configured chunk_timeout (the select on the stream errors on the timeout branch).","commonSituations":"Flaky corporate networks or mobile links dropping packets mid-transfer, GCS connections throttled or silently dropped by middleboxes, extremely slow signed-URL endpoints, or very large files over an unstable VPN.","solutions":["Retry download_file; a fresh request usually gets a working connection","Increase chunk_timeout if downloads legitimately pause on slow links","Check network path (VPN, proxy, firewall) for idle-connection resets","Verify the object size with a HEAD request; retry with range requests for very large objects"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in 0..3 {\n    match download_file(&client, &url, &dest).await {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"stalled\") && attempt < 2 => {\n            tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await;\n        },\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Retry stalled downloads with exponential backoff","Tune chunk_timeout to fit the slowest expected network","Avoid transfers over known-unstable links (VPNs, mobile) for large artifacts"],"tags":["gcs","timeout","network","streaming"],"backgroundTag":"download-stalled-timeout","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}