{"record":{"id":"b7dc35e39c0ef84a","repo":"can1357/oh-my-pi","slug":"timed-out-downloading-release-binary-after-15-minu","errorCode":null,"errorMessage":"Timed out downloading release binary after 15 minutes","messagePattern":"Timed out downloading release binary after 15 minutes","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/update-cli.ts","lineNumber":306,"sourceCode":"\tfetchImpl?: Fetch;\n}\n\n/**\n * Download a binary and verify its GitHub-reported size and SHA-256 digest.\n */\nexport async function downloadVerifiedBinary(options: VerifiedBinaryDownloadOptions): Promise<void> {\n\tconst fetchImpl = options.fetchImpl ?? fetch;\n\tawait unlinkIfExists(options.targetPath);\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchImpl(options.url, {\n\t\t\tredirect: \"follow\",\n\t\t\tsignal: withTimeoutSignal(BINARY_DOWNLOAD_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tif (isTimeoutError(err)) {\n\t\t\tthrow new Error(\"Timed out downloading release binary after 15 minutes\", { cause: err });\n\t\t}\n\t\tif (isUnsupportedProxyError(err)) throw new Error(unsupportedProxyMessage(), { cause: err });\n\t\tthrow err;\n\t}\n\tif (!response.ok || !response.body) {\n\t\tthrow new Error(`Download failed: ${response.statusText}`);\n\t}\n\n\tconst hash = createHash(\"sha256\");\n\tlet size = 0;\n\tconst verifier = new Transform({\n\t\ttransform(chunk, _encoding, callback) {\n\t\t\tsize += chunk.byteLength;\n\t\t\tif (size > options.expectedSize) {\n\t\t\t\tcallback(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Downloaded binary size mismatch: expected ${options.expectedSize} bytes, received at least ${size}`,\n\t\t\t\t\t),","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/update-cli.ts#L288-L324","documentation":"Thrown by downloadVerifiedBinary when the fetch of the release binary is aborted by BINARY_DOWNLOAD_TIMEOUT_MS (15 minutes) before the response headers arrive. The abort is detected via isTimeoutError and rethrown with a human-readable message while preserving the original AbortError as `cause`. This prevents the updater from hanging indefinitely on a stalled connection.","triggerScenarios":"fetchImpl(options.url) rejects with a timeout AbortError because the CDN/object-storage endpoint did not deliver response headers within 15 minutes — very slow or stalled network, a hanging proxy, or a black-holing connection to the release download host.","commonSituations":"Downloading on a constrained uplink (e.g. corporate VPN throttling GitHub's CDN); a misconfigured middlebox that accepts the TCP connection but never responds; laptop sleeping mid-download.","solutions":["Re-run the update on a stable connection — the timeout is per-attempt, so a simple retry often succeeds.","Check proxy/VPN interference: temporarily disable the VPN or try without HTTP(S)_PROXY set.","Download the release asset manually from the GitHub releases page and install it by hand if the network to the CDN is persistently slow."],"exampleFix":"// before: flaky network causes timeout\n$ omp update\n// after: pre-download asset manually, or retry on stable network\n$ omp update --force","handlingStrategy":"retry","validationCode":"const proxy = process.env.HTTPS_PROXY ?? process.env.HTTP_PROXY;\nif (proxy && proxy.startsWith(\"socks\")) throw new Error(\"Unsupported SOCKS proxy would stall download\");","typeGuard":"function isDownloadTimeout(err: unknown): boolean {\n  return err instanceof Error && err.message.includes(\"Timed out downloading release binary\");\n}","tryCatchPattern":"try {\n  await runUpdate();\n} catch (err) {\n  if (isDownloadTimeout(err)) {\n    await Bun.sleep(5000);\n    return runUpdate(); // fresh 15-minute budget per attempt\n  }\n  throw err;\n}","preventionTips":["Run updates on wired/stable connections","Avoid VPNs or throttling proxies for large binary downloads","Prefer `omp update --check` first to gauge connectivity before committing to the download"],"tags":["network","timeout","download","update-cli"],"backgroundTag":"download-timeout","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}