{"record":{"id":"1aff7517e0b2893e","repo":"xai-org/grok-build","slug":"gcs-download-failed","errorCode":null,"errorMessage":"GCS download failed: {}","messagePattern":"GCS download failed: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/agent/session_registry_client.rs","lineNumber":368,"sourceCode":"        let url = format!(\"{}/sessions/{}/download\", self.base_url, session_id);\n        let builder = self\n            .get(&url)\n            .query(&[(\"file\", file), (\"turn\", &turn.to_string())]);\n        let (response, stamp) = self.send_authed(builder, \"session download\").await?;\n        if !response.status().is_success() {\n            return Err(self.check_response(response, stamp.as_ref(), \"session download\"));\n        }\n        let resp: DownloadResponse = response.json().await.context(\"parse download response\")?;\n\n        // Stream from the signed GCS URL directly to disk (archives can be hundreds of MB)\n        let mut gcs_response = self\n            .raw_client\n            .get(&resp.download_url)\n            .send()\n            .await\n            .context(\"download from GCS\")?;\n        if !gcs_response.status().is_success() {\n            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!(","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/agent/session_registry_client.rs#L350-L386","documentation":"download_file fetches a session artifact from a signed GCS URL via the raw HTTP client. After sending the GET, any non-2xx status is converted into this error carrying the HTTP status code. It signals that the signed URL was rejected or the object is not retrievable, not a local I/O problem.","triggerScenarios":"Calling download_file (e.g. via the session registry client) when the GCS GET returns a non-success status such as 403 (expired/revoked signed URL), 404 (object deleted), or 5xx from Google Cloud Storage.","commonSituations":"Signed download URLs expiring before use, artifacts garbage-collected after a session is reaped, proxy/firewall blocking storage.googleapis.com, or GCS transient outages returning 500/503.","solutions":["Re-fetch a fresh download URL from the session registry and retry the download immediately","Verify the object still exists in the GCS bucket (gsutil ls / console) for the session id","Check network/proxy configuration so storage.googleapis.com is reachable","Retry on 5xx with backoff; treat 403/404 as fatal and obtain a new session or artifact"],"exampleFix":"// before\nlet resp = client.raw_client.get(&stale_url).send().await?;\n// after: obtain a fresh URL then retry once on failure\nlet resp = client.raw_client.get(&fresh_url).send().await?;\nif !resp.status().is_success() {\n    let fresh = registry.get_download_url(&session_id).await?;\n    resp = client.raw_client.get(&fresh).send().await?;\n}","handlingStrategy":"retry","validationCode":"// Optionally pre-check reachability\nlet head = client.raw_client.head(&download_url).send().await?;\nif !head.status().is_success() {\n    eprintln!(\"download URL unusable ({}); refresh it\", head.status());\n}","typeGuard":null,"tryCatchPattern":"match download_file(&client, &url, &dest).await {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"GCS download failed\") => {\n        let fresh = registry.get_download_url(&session_id).await?;\n        download_file(&client, &fresh, &dest).await?;\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Download immediately after obtaining the signed URL — they expire","Wrap downloads in one bounded retry with fresh URL re-fetch","Monitor object retention policies so artifacts outlive expected download windows"],"tags":["gcs","http","network","download"],"backgroundTag":"gcs-signed-url-download-failed","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}