{"record":{"id":"e05a70d80838298b","repo":"vercel/turborepo","slug":"failed-to-download-response-status","errorCode":null,"errorMessage":"Failed to download: ${response.status}","messagePattern":"Failed to download: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/turbo-utils/src/examples.ts","lineNumber":346,"sourceCode":"    controller.abort();\n  }, DOWNLOAD_TIMEOUT);\n\n  // Track all write streams so we can clean them up on abort/error\n  const writeStreams: Array<Writable> = [];\n\n  // Pre-resolve root once for performance (avoids calling resolve() per entry)\n  const resolvedRoot = resolve(root);\n\n  // Cache created directories to avoid redundant mkdirSync calls\n  const createdDirs = new Set<string>();\n\n  try {\n    const response = await fetch(url, {\n      ...buildFetchInit(url),\n      signal: controller.signal\n    });\n    if (!response.ok || !response.body) {\n      throw new Error(`Failed to download: ${response.status}`);\n    }\n\n    const body = Readable.fromWeb(response.body as ReadableStream);\n    let rootPath: string | null = null;\n\n    // Track all file write operations so we can wait for them to complete\n    const fileWritePromises: Array<Promise<void>> = [];\n\n    const parser = new Parser({\n      filter: (p: string) => {\n        // Determine the unpacked root path dynamically instead of hardcoding.\n        // This avoids issues when the repository has been renamed.\n        if (rootPath === null) {\n          const pathSegments = p.split(\"/\");\n          rootPath = pathSegments.length ? pathSegments[0] : null;\n        }\n        return filter(p, rootPath);\n      },","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/vercel/turborepo/blob/f9245100cf0d31d96628804ead485f6bf226e55a/packages/turbo-utils/src/examples.ts#L328-L364","documentation":"Thrown by streamingExtract in @turbo-utils/examples.ts when the HTTP response for a tarball download is not ok (non-2xx status) or has no body. This is the streaming path create-turbo uses to fetch the examples tarball (or a custom repo tarball URL). The status code is embedded in the message so you can tell a 404 (wrong path/branch) from a 403/429 (rate limit).","triggerScenarios":"Calling createProject()/streamingExtract() where the fetch to the tarball URL (e.g. https://codeload.github.com/vercel/turborepo/tar.gz/canary or a user-supplied repo URL) returns non-2xx: 404 for a nonexistent example/repo/branch, 403 or 429 for GitHub rate limiting, 407/5xx behind a corporate proxy, or a response with a null body.","commonSituations":"Running create-turbo behind a proxy or firewall that rewrites responses, hitting GitHub's anonymous API/tarball rate limit from CI shared IPs, typo in --example name or a custom repo URL pointing at a nonexistent branch, or being fully offline.","solutions":["Decode the message for the HTTP status: 404 means wrong example name/repo/branch, 403/429 means rate limited (wait or use a different network/token), 5xx means retry later","Check connectivity/proxy: HTTPS_PROXY/HTTP_PROXY env vars must allow codeload.github.com","If rate limited, wait a few minutes or download the tarball manually and use a local path/template instead","Retry the create-turbo command; transient GitHub failures are common","If offline, use an existing local template directory instead of fetching"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-check the tarball URL before calling createProject\nasync function tarballReachable(url: string): Promise<boolean> {\n  const res = await fetch(url, { method: \"HEAD\" });\n  return res.ok;\n}\n// const ok = await tarballReachable(\"https://codeload.github.com/vercel/turborepo/tar.gz/canary\");","typeGuard":null,"tryCatchPattern":"try {\n  await createProject(opts);\n} catch (err) {\n  const status = Number(/Failed to download: (\\d+)/.exec(String(err?.message))?.[1]);\n  if (status === 429 || status >= 500) {\n    await sleep(backoffMs); // exponential backoff, then retry once or twice\n  } else if (status === 404) {\n    throw new Error(\"Example or branch not found - check the name/URL\", { cause: err });\n  } else {\n    throw err;\n  }\n}","preventionTips":["Run create-turbo from networks with direct access to codeload.github.com (check HTTPS_PROXY)","In CI, cache or vendor template tarballs instead of fetching per-run to avoid rate limits","Pre-validate custom repo URLs with a HEAD request before invoking the tool"],"tags":["network","download","http","github","create-turbo","cli"],"backgroundTag":"http-download-failed","analyzedSha":"f9245100cf0d31d96628804ead485f6bf226e55a","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}