evanw/esbuild · error · Error

Could not find in archive

Error message

Could not find ${JSON.stringify(subpath)} in archive

What it means

In extractFileFromTarGzip (lib/npm/node-install.ts:84), after successfully decompressing the tarball the code scans tar headers looking for an entry named `package/<subpath>` (e.g. package/bin/esbuild). If no such entry exists by end of archive, it throws. This means the downloaded tarball is valid but does not contain the expected binary path.

Solutions

  1. Ensure the esbuild package and the @esbuild/* platform package are pinned to the same version.
  2. Clear caches (npm cache clean / pnpm store prune) and reinstall.
  3. Verify the registry mirror serves the correct, current tarball for the exact version.
  4. Retry the install to rule out a transient mirror issue.
Defensive patterns

Strategy: retry

Validate before calling

// Verify the expected entry exists in a fetched tarball before trusting it.
const tar = require('tar-stream') // or similar
async function hasEntry(buf, name) {
  return new Promise(resolve => {
    const s = tar.extract()
    let found = false
    s.on('entry', (h, stream, next) => {
      if (h.name === name) found = true
      stream.on('end', next); stream.resume()
    })
    s.on('finish', () => resolve(found))
    s.end(buf)
  })
}

Prevention

When it happens

Trigger: The @esbuild/* package tarball downloaded during the fallback path is valid gzip and a valid tar, but lacks the expected file entry (e.g. version skew where the package layout changed, or the registry served a tarball for a different version/package).

Common situations: Version mismatch between the esbuild JS package and the @esbuild/* platform package it tries to fetch; registry mirror caching a stale/renamed artifact; a proxy serving a similarly-named but wrong tarball.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/28177237df314b71. Report an issue: GitHub.

Appendix: source

Thrown at lib/npm/node-install.ts:102

function extractFileFromTarGzip(buffer: Buffer, subpath: string): Buffer {
  try {
    buffer = zlib.unzipSync(buffer)
  } catch (err: any) {
    throw new Error(`Invalid gzip data in archive: ${err && err.message || err}`)
  }
  let str = (i: number, n: number) => String.fromCharCode(...buffer.subarray(i, i + n)).replace(/\0.*$/, '')
  let offset = 0
  subpath = `package/${subpath}`
  while (offset < buffer.length) {
    let name = str(offset, 100)
    let size = parseInt(str(offset + 124, 12), 8)
    offset += 512
    if (!isNaN(size) && size >= 0) {
      if (name === subpath) return buffer.subarray(offset, offset + size)
      offset += (size + 511) & ~511
    }
  }
  throw new Error(`Could not find ${JSON.stringify(subpath)} in archive`)
}

function installUsingNPM(pkg: string, subpath: string, binPath: string): void {
  // Erase "npm_config_global" so that "npm install --global esbuild" works.
  // Otherwise this nested "npm install" will also be global, and the install
  // will deadlock waiting for the global installation lock.
  const env = { ...process.env, npm_config_global: undefined }

  // Create a temporary directory inside the "esbuild" package with an empty
  // "package.json" file. We'll use this to run "npm install" in.
  const esbuildLibDir = path.dirname(require.resolve('esbuild'))
  const installDir = path.join(esbuildLibDir, 'npm-install')
  fs.mkdirSync(installDir)
  try {
    fs.writeFileSync(path.join(installDir, 'package.json'), '{}')

    // Run "npm install" in the temporary directory which should download the
    // desired package. Try to avoid unnecessary log output. This uses the "npm"

View on GitHub (pinned to f6058f8364)