{"record":{"id":"ead49ab25659900c","repo":"JuliusBrussee/caveman","slug":"off-states-downloadstalled-timeoutseconds-line-nfix-off","errorCode":null,"errorMessage":"${OFF_STATES.downloadStalled(timeoutSeconds).line}\\nfix: ${OFF_STATES.downloadStalled(timeoutSeconds).fix}","messagePattern":"(.+?)\\\\nfix: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":2391,"sourceCode":"  const line = `${name}  ${platform.os}/${platform.arch}  …`;\n  if (interactive()) process.stderr.write(line);\n  else console.error(line);\n}\n\nfunction installProgressComplete(\n  name: string,\n  platform: { os: string; arch: string },\n  bytes: number,\n) {\n  const line = `${name}  ${platform.os}/${platform.arch}  ${(bytes / 1_000_000).toFixed(1)} MB  checksum verified`;\n  if (interactive()) process.stderr.write(`\\r${line}\\n`);\n  else console.error(line);\n}\n\nfunction setupInstallFailure(error: unknown, timeoutSeconds: number): never {\n  if (interactive()) process.stderr.write(\"\\n\");\n  if (error instanceof BinaryDownloadError && error.kind === \"stalled\") {\n    throw new Error(`${OFF_STATES.downloadStalled(timeoutSeconds).line}\\nfix: ${OFF_STATES.downloadStalled(timeoutSeconds).fix}`);\n  }\n  throw new Error(`${OFF_STATES.downloadUnreachable.line}\\nfix: ${OFF_STATES.downloadUnreachable.fix}`);\n}\n\nfunction printInstallResult(\n  installed: InstalledBinary[],\n  platform: { os: string; arch: string },\n  binDir: string,\n  json: boolean,\n  continuing = false,\n) {\n  if (json) {\n    print({\n      release: BINARY_RELEASE,\n      platform: `${platform.os}/${platform.arch}`,\n      target: binDir,\n      binaries: installed,\n      next: \"caveman claude\",","sourceCodeStart":2373,"sourceCodeEnd":2409,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L2373-L2409","documentation":"setupInstallFailure translates binary download failures into user-facing errors. A BinaryDownloadError with kind 'stalled' (progress stopped mid-download) throws the downloadStalled off-state line plus its fix; any other download failure throws the generic downloadUnreachable line plus fix.","triggerScenarios":"Binary download stalling: connection freezes with no bytes for the stall timeout, a proxy/firewall throttles the CDN to zero throughput, or the network drops without closing the socket. Any non-stall error (DNS failure, 403/404, TLS error) produces the downloadUnreachable variant.","commonSituations":"Corporate proxies that accept the connection but stop forwarding data; flaky Wi-Fi mid-install; CI runners with aggressive network timeouts; rate-limited CDN.","solutions":["Retry the install command — stalls are often transient network issues.","Check proxy/firewall settings and ensure the release CDN host is reachable (curl the download URL).","Increase the stall/timeout budget via the relevant timeout env (e.g. CAVE_SETUP_TIMEOUT) on slow connections.","Switch networks (VPN off/on, different Wi-Fi) or download the binaries manually."],"exampleFix":"// before\n$ cave setup   # download stalls behind corporate proxy\nError: download stalled after 30s\\nfix: check network...\n\n// after\n$ export HTTPS_PROXY=http://proxy.corp:8080\n$ cave setup   # download completes","handlingStrategy":"retry","validationCode":"const res = await fetch(downloadUrl, { method: 'HEAD', signal: AbortSignal.timeout(10000) });\nif (!res.ok) console.warn(`download host unreachable (${res.status}) before starting setup`);","typeGuard":null,"tryCatchPattern":"try {\n  await runSetup();\n} catch (error) {\n  if (error instanceof BinaryDownloadError && error.kind === 'stalled') {\n    await retry(runSetup, { attempts: 3, backoffMs: 5000 }); // transient stall\n  } else throw error;\n}","preventionTips":["Use a stable network or configure HTTPS_PROXY before installing","Increase CAVE_SETUP_TIMEOUT on slow connections","Warm the download URL with curl in CI to fail fast on proxy/CDN issues","Pre-download binaries manually when behind restrictive firewalls"],"tags":["network","download","timeout"],"backgroundTag":"request-timeout","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}