{"record":{"id":"3fb834c030c61c6d","repo":"google-gemini/gemini-cli","slug":"download-failed-no-response-body","errorCode":null,"errorMessage":"Download failed: No response body","messagePattern":"Download failed: No response body","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/gemma/setup.ts","lineNumber":84,"sourceCode":"  } else {\n    process.stderr.write(`\\r  Downloaded ${formatBytes(downloaded)}`);\n  }\n}\n\nasync function downloadFile(url: string, destPath: string): Promise<void> {\n  const tmpPath = destPath + '.downloading';\n  if (fs.existsSync(tmpPath)) {\n    fs.unlinkSync(tmpPath);\n  }\n\n  const response = await fetch(url, { redirect: 'follow' });\n  if (!response.ok) {\n    throw new Error(\n      `Download failed: HTTP ${response.status} ${response.statusText}`,\n    );\n  }\n  if (!response.body) {\n    throw new Error('Download failed: No response body');\n  }\n\n  const contentLength = response.headers.get('content-length');\n  const totalBytes = contentLength ? parseInt(contentLength, 10) : null;\n  let downloadedBytes = 0;\n\n  const fileStream = fs.createWriteStream(tmpPath);\n  const reader = response.body.getReader();\n\n  try {\n    for (;;) {\n      const { done, value } = await reader.read();\n      if (done) break;\n      const writeOk = fileStream.write(value);\n      if (!writeOk) {\n        await new Promise<void>((resolve) => fileStream.once('drain', resolve));\n      }\n      downloadedBytes += value.byteLength;","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/cli/src/commands/gemma/setup.ts#L66-L102","documentation":"After confirming the HTTP response is OK (response.ok is true), downloadFile() checks that response.body is present. If the server returned a success status without a readable body stream, the download cannot proceed. This is a defensive check for an unusual edge case in the fetch response.","triggerScenarios":"A server or proxy returns HTTP 200 with a null or absent body stream. This can occur with certain reverse proxy configurations, HTTP/2 edge cases, HEAD-like responses misrouted as GET, or server bugs.","commonSituations":"Misconfigured reverse proxy stripping the response body; unusual CDN behavior; transparent proxy intercepting and reformatting responses; HTTP/2 protocol quirks.","solutions":["Retry the download — may be transient.","Check proxy, VPN, and CDN configuration for body-stripping behavior.","Try a different network connection to rule out a local proxy issue.","If persistent, the hosting server is likely misconfigured — report the issue."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"async function downloadWithBodyRetry(url: string, dest: string, maxRetries = 3): Promise<void> {\n  for (let attempt = 1; attempt <= maxRetries; attempt++) {\n    try {\n      await downloadFile(url, dest);\n      return;\n    } catch (e) {\n      if (e instanceof Error && e.message === 'Download failed: No response body' && attempt < maxRetries) {\n        await new Promise((r) => setTimeout(r, 1000 * attempt));\n        continue;\n      }\n      throw e;\n    }\n  }\n}","preventionTips":["Retry the download — a missing body is often transient.","Check for proxy, VPN, or CDN configurations that may strip response bodies.","Try a different network connection to isolate local proxy issues."],"tags":["network","download","gemma","http"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}