{"id":"be445a61ad9c0621","repo":"evanw/esbuild","slug":"invalid-gzip-data-in-archive-err-err-message","errorCode":null,"errorMessage":"Invalid gzip data in archive: ${err && err.message || err}","messagePattern":"Invalid gzip data in archive: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/npm/node-install.ts","lineNumber":88,"sourceCode":"function fetch(url: string): Promise<Buffer> {\n  return new Promise((resolve, reject) => {\n    https.get(url, res => {\n      if ((res.statusCode === 301 || res.statusCode === 302) && res.headers.location)\n        return fetch(res.headers.location).then(resolve, reject)\n      if (res.statusCode !== 200)\n        return reject(new Error(`Server responded with ${res.statusCode}`))\n      let chunks: Buffer[] = []\n      res.on('data', chunk => chunks.push(chunk))\n      res.on('end', () => resolve(Buffer.concat(chunks)))\n    }).on('error', reject)\n  })\n}\n\nfunction extractFileFromTarGzip(buffer: Buffer, subpath: string): Buffer {\n  try {\n    buffer = zlib.unzipSync(buffer)\n  } catch (err: any) {\n    throw new Error(`Invalid gzip data in archive: ${err && err.message || err}`)\n  }\n  let str = (i: number, n: number) => String.fromCharCode(...buffer.subarray(i, i + n)).replace(/\\0.*$/, '')\n  let offset = 0\n  subpath = `package/${subpath}`\n  while (offset < buffer.length) {\n    let name = str(offset, 100)\n    let size = parseInt(str(offset + 124, 12), 8)\n    offset += 512\n    if (!isNaN(size) && size >= 0) {\n      if (name === subpath) return buffer.subarray(offset, offset + size)\n      offset += (size + 511) & ~511\n    }\n  }\n  throw new Error(`Could not find ${JSON.stringify(subpath)} in archive`)\n}\n\nfunction installUsingNPM(pkg: string, subpath: string, binPath: string): void {\n  // Erase \"npm_config_global\" so that \"npm install --global esbuild\" works.","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/lib/npm/node-install.ts#L70-L106","documentation":"`extractFileFromTarGzip` (`node-install.ts:88`) decompresses the npm tarball with `zlib.unzipSync`; if that throws, the downloaded `.tgz` is not valid gzip. The catch wraps the zlib error and rethrows a clearer message. This is the fallback path used when the optional platform package wasn't installed via npm.","triggerScenarios":"The fallback downloader (`downloadDirectlyFromNPM`) fetches `https://registry.npmjs.org/.../-/....tgz` and the response body cannot be gunzipped. This path runs only when the optional `@esbuild/<platform>` package is missing AND the nested `npm install` workaround also failed.","commonSituations":"Corporate proxy/MITM returning an HTML error page instead of the tarball; corrupted download from a flaky registry mirror; npm registry returning a 200 with an error body; running offline with a partial cache; antivirus mangling the byte stream.","solutions":["Retry the install on a stable network connection (the failure is usually transient corruption).","Check that your registry config (`npm config get registry`) points at a real npm-compatible registry that serves valid tarballs.","Disable proxies/MITM that rewrite npm traffic, or configure them to pass the registry through.","Use `npm install` without `--no-optional` so the normal optionalDependencies path is used and the fallback downloader is never invoked.","Verify the tarball manually: `curl -sI <url>` should report 200 and `Content-Type: application/octet-stream`."],"exampleFix":"# before\nnpm install --no-optional esbuild  # forces broken fallback path\n\n# after\nnpm install esbuild  # uses optionalDependencies normally","handlingStrategy":"retry","validationCode":"import { gunzipSync } from 'zlib'\nfunction looksLikeValidGzip(buf: Buffer): boolean {\n  return buf.length > 2 && buf[0] === 0x1f && buf[1] === 0x8b\n}\n// before passing to a tarball extractor:\nif (!looksLikeValidGzip(downloaded)) throw new Error('download is not gzip')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Don't use --no-optional; let normal optionalDependencies resolve the binary.","Verify registry/proxy configuration before relying on the fallback downloader.","Retry installs on transient network corruption.","Mirror the registry on a stable internal server for offline/restricted networks."],"tags":["install","network","registry","gzip","fallback","download"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}