{"record":{"id":"b191f56f586efd79","repo":"yamadashy/repomix","slug":"failed-to-download-github-archive-after-retries","errorCode":null,"errorMessage":"Failed to download GitHub archive after ${retries} attempts. ${lastError?.message || 'Unknown error'}","messagePattern":"Failed to download GitHub archive after (.+?) attempts\\. (.+?)","errorType":"exception","errorClass":"RepomixError","httpStatus":null,"severity":"error","filePath":"src/core/git/gitHubArchive.ts","lineNumber":101,"sourceCode":"        const isNotFoundError =\n          lastError instanceof RepomixError &&\n          (lastError.message.includes('not found') || lastError.message.includes('404'));\n        if (isNotFoundError && archiveUrls.length > 1) {\n          break;\n        }\n\n        // If it's the last attempt, don't wait\n        if (attempt < retries) {\n          const delay = Math.min(1000 * 2 ** (attempt - 1), 5000); // Exponential backoff, max 5s\n          logger.trace(`Retrying in ${delay}ms...`);\n          await new Promise((resolve) => setTimeout(resolve, delay));\n        }\n      }\n    }\n  }\n\n  // If we get here, all attempts failed\n  throw new RepomixError(\n    `Failed to download GitHub archive after ${retries} attempts. ${lastError?.message || 'Unknown error'}`,\n  );\n};\n\n/**\n * Downloads and extracts a tar.gz archive from a single URL using streaming pipeline.\n * The HTTP response is streamed through gunzip and tar extract directly to disk,\n * without writing a temporary archive file.\n */\nconst downloadAndExtractArchive = async (\n  archiveUrl: string,\n  targetDirectory: string,\n  timeout: number,\n  onProgress?: ProgressCallback,\n  deps: ArchiveDownloadDeps = defaultDeps,\n): Promise<void> => {\n  const controller = new AbortController();\n  const timeoutId = setTimeout(controller.abort.bind(controller), timeout);","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/yamadashy/repomix/blob/f465ad909315a22120636baf03fa5e28701a50cb/src/core/git/gitHubArchive.ts#L83-L119","documentation":"downloadGitHubArchive retries downloading the repository archive from GitHub (codeload/API endpoints) a fixed number of times; if every attempt fails it throws this error with the last attempt's error message. It indicates a persistent network, DNS, proxy, or GitHub availability problem rather than an HTTP API status error.","triggerScenarios":"All retry attempts of downloadGitHubArchive fail — repeated network timeouts, connection resets, DNS failures, or streaming pipeline errors across every attempt; lastError's message is embedded in the output.","commonSituations":"Corporate proxy or firewall blocking codeload.github.com; offline or flaky network; DNS not resolving; GitHub incident/ outage; TLS interception certificates breaking the fetch pipeline.","solutions":["Check network access to github.com / codeload.github.com (curl -I https://codeload.github.com) and fix proxy/VPN/firewall settings.","Retry later or check the GitHub status page — the error may be a transient GitHub-side outage.","If retries are exhausted due to a slow connection, increase the timeout/retry budget or use a more reliable network, then re-run.","Fall back to cloning with git directly (repomix supports local paths / git clone instead of archive download)."],"exampleFix":"// before\nnpx repomix --remote https://github.com/user/repo   // fails behind corporate proxy\n// after\nexport HTTPS_PROXY=http://proxy.corp.local:8080\nnpx repomix --remote https://github.com/user/repo","handlingStrategy":"retry","validationCode":"const ok = await fetch('https://codeload.github.com/owner/repo/tar.gz/HEAD', { method: 'HEAD' })\n  .then(r => r.ok).catch(() => false);\nif (!ok) throw new Error('GitHub unreachable from this network; fix proxy/DNS before running.');","typeGuard":null,"tryCatchPattern":"try {\n  await pack({ remote: url });\n} catch (e) {\n  if (e instanceof RepomixError && e.message.startsWith('Failed to download GitHub archive after')) {\n    // transient network issue: back off and retry, or fall back to git clone\n    await new Promise(r => setTimeout(r, 5000));\n  } else throw e;\n}","preventionTips":["Configure HTTPS_PROXY correctly on corporate networks before running remote packing.","Monitor githubstatus.com and avoid scheduled runs during incidents.","Prefer a stable wired connection / reliable CI runners; archive downloads of big repos are bandwidth-sensitive.","Consider cloning with git instead of the archive path when networks are unreliable."],"tags":["network","github","download","retry-exhausted"],"backgroundTag":"download-failed-after-retries","analyzedSha":"f465ad909315a22120636baf03fa5e28701a50cb","analyzedAt":"2026-08-29T01:27:42.024Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}