evanw/esbuild · critical · Error

Expected ${JSON.stringify(packageJSON.version)} but got ${JS

Error message

Expected ${JSON.stringify(packageJSON.version)} but got ${JSON.stringify(stdout)}

What it means

After install, `validateBinaryVersion` runs `esbuild --version` and requires the output to exactly equal `packageJSON.version` (the version declared in `npm/esbuild/package.json`). If the binary prints a different version, the package was assembled incorrectly: the JS shim and the native binary are out of sync.

Source

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

      let os = 'this version of macOS'
      try {
        os = 'macOS ' + child_process.execFileSync('sw_vers', ['-productVersion']).toString().trim()
      } catch {
      }
      throw new Error(`The "esbuild" package cannot be installed because ${os} is too outdated.

The Go compiler (which esbuild relies on) no longer supports ${os},
which means the "esbuild" binary executable can't be run. You can either:

  * Update your version of macOS to one that the Go compiler supports
  * Use the "esbuild-wasm" package instead of the "esbuild" package
  * Build esbuild yourself using an older version of the Go compiler
`)
    }
    throw err
  }
  if (stdout !== packageJSON.version) {
    throw new Error(`Expected ${JSON.stringify(packageJSON.version)} but got ${JSON.stringify(stdout)}`)
  }
}

function isYarn(): boolean {
  const { npm_config_user_agent } = process.env
  if (npm_config_user_agent) {
    return /\byarn\//.test(npm_config_user_agent)
  }
  return false
}

function fetch(url: string): Promise<Buffer> {
  return new Promise((resolve, reject) => {
    https.get(url, res => {
      if ((res.statusCode === 301 || res.statusCode === 302) && res.headers.location)
        return fetch(res.headers.location).then(resolve, reject)
      if (res.statusCode !== 200)
        return reject(new Error(`Server responded with ${res.statusCode}`))

View on GitHub (pinned to 6ff1d8b0d8)

Solutions

  1. Clear npm/yarn cache (`npm cache clean --force`) and reinstall so both JS and binary come from the same version.
  2. Check for and remove duplicate esbuild versions across the dependency tree (`npm ls esbuild`).
  3. Unset any `ESBUILD_BINARY_PATH` override pointing at a stale binary.
  4. Rebuild Docker images from clean so no stale binary layer persists.
  5. If using a vendored/forked esbuild, ensure its binary build embeds the same version string as the JS package.json.

Example fix

# before: stale binary overrides
export ESBUILD_BINARY_PATH=/opt/old/esbuild-0.14.0

# after
unset ESBUILD_BINARY_PATH
npm cache clean --force && rm -rf node_modules && npm install
Defensive patterns

Strategy: validation

Validate before calling

import { execFileSync } from 'child_process'
import pkg from 'esbuild/package.json'
function verifyBinaryVersion(binPath: string) {
  const v = execFileSync(binPath, ['--version']).toString().trim()
  if (v !== pkg.version) {
    throw new Error(`esbuild binary ${v} != package ${pkg.version}; reinstall esbuild`)
  }
}

Prevention

When it happens

Trigger: The postinstall hook runs the just-installed `esbuild` binary with `--version` and the printed version differs from the JS package's declared version. This indicates the wrong-platform binary got placed, a stale binary is on disk, or the package was republished with mismatched artifacts.

Common situations: A monorepo hoisting two different esbuild versions where the wrong binary is linked into the install dir; a third-party `esbuild` wrapper package shadowing the real binary; tampered/cached binary in a Docker layer; manual `ESBUILD_BINARY_PATH` pointing at an older esbuild; corrupted npm cache serving mismatched tarballs.

Related errors


AI-assisted analysis of evanw/esbuild@6ff1d8b0d8 (2026-08-03). Data as JSON: /data/errors/712951dd1d844f9b.json. Report an issue: GitHub.