{"record":{"id":"0cfea393286ce70a","repo":"can1357/oh-my-pi","slug":"browser-download-failed-response-status-resp","errorCode":null,"errorMessage":"Browser download failed (${response.status} ${response.statusText}) from ${url}","messagePattern":"Browser download failed \\((.+?) (.+?)\\) from (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/utils/src/browsers.ts","lineNumber":344,"sourceCode":"\nasync function pathExists(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait fsp.access(filePath);\n\t\treturn true;\n\t} catch (error) {\n\t\tif (isMissingPath(error)) return false;\n\t\tthrow error;\n\t}\n}\n\nasync function downloadArchive(\n\turl: URL,\n\tdestination: string,\n\tonProgress: ((progress: BrowserDownloadProgress) => void) | undefined,\n): Promise<void> {\n\tconst response = await fetch(url);\n\tif (!response.ok || !response.body) {\n\t\tthrow new Error(`Browser download failed (${response.status} ${response.statusText}) from ${url}`);\n\t}\n\tconst totalBytes = Number(response.headers.get(\"content-length\") ?? 0);\n\tconst file = await fsp.open(destination, \"wx\");\n\tlet downloadedBytes = 0;\n\ttry {\n\t\tconst reader = response.body.getReader();\n\t\tfor (;;) {\n\t\t\tconst chunk = await reader.read();\n\t\t\tif (chunk.done) break;\n\t\t\tlet offset = 0;\n\t\t\twhile (offset < chunk.value.byteLength) {\n\t\t\t\tconst write = await file.write(chunk.value, offset, chunk.value.byteLength - offset, null);\n\t\t\t\tif (write.bytesWritten === 0) throw new Error(`Browser download stalled while writing ${destination}`);\n\t\t\t\toffset += write.bytesWritten;\n\t\t\t}\n\t\t\tdownloadedBytes += chunk.value.byteLength;\n\t\t\tonProgress?.({ downloadedBytes, totalBytes });\n\t\t}","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/browsers.ts#L326-L362","documentation":"downloadArchive streams the Chrome-for-Testing zip from storage.googleapis.com to disk; if the response is not ok or has no body, this Error is thrown with status, statusText, and the full URL. It indicates the binary download itself failed, distinct from the metadata fetch failure.","triggerScenarios":"install() -> downloadArchive when the archive GET returns non-2xx: wrong buildId (404, build never published for that platform), storage.googleapis.com 403/429 from rate limiting or blocked egress, or an ok status with a null body (e.g. 204 from a proxy).","commonSituations":"Typos or truncated buildIds in config (404); requesting builds for platforms that don't exist (404); corporate firewalls blocking storage.googleapis.com; GCS rate limits during large parallel CI installs.","solutions":["Verify the buildId and platform combination exists: open the URL from the error message in a browser or check https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-browsers.json.","Retry with backoff for 429/5xx; serialize parallel installs in CI to avoid rate limits.","Confirm egress to storage.googleapis.com (proxy/firewall allowlist).","Use a known-good pinned buildId with a published browser artifact."],"exampleFix":"// before\nconst buildId = '131.0'; // malformed -> 404 on archive GET\nawait install({ browser: Browser.CHROME, buildId, cacheDir });\n// after\nconst buildId = '131.0.6778.204'; // exact version with published artifacts\nawait install({ browser: Browser.CHROME, buildId, cacheDir });","handlingStrategy":"retry","validationCode":"// verify the artifact exists before install\nconst probe = await fetch(`https://storage.googleapis.com/chrome-for-testing-public/${buildId}/linux64/chrome-linux64.zip`, { method: 'HEAD' });\nif (!probe.ok) throw new Error(`No Chrome archive for buildId=${buildId} platform=linux64 (HTTP ${probe.status})`);","typeGuard":"null","tryCatchPattern":"async function installWithRetry(opts: InstallOptions) {\n  for (let attempt = 0; ; attempt++) {\n    try {\n      return await install(opts);\n    } catch (err) {\n      const m = /Browser download failed \\((\\d+) /.exec(String(err));\n      if (m && (m[1].startsWith('5') || m[1] === '429') && attempt < 3) {\n        await Bun.sleep(2 ** attempt * 1000); // backoff for 429/5xx\n        continue;\n      }\n      throw err; // 4xx (bad buildId) will not heal by retrying\n    }\n  }\n}","preventionTips":["Validate buildId + platform against known-good-versions-with-browsers.json before installing.","Serialize or throttle parallel installs to avoid 429 rate limits.","Allowlist storage.googleapis.com in restricted networks.","Retry only transient statuses (429, 5xx); 404 means fix the buildId."],"tags":["network","http","download","chrome-for-testing"],"backgroundTag":"browser-download-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}