evanw/esbuild · error · Error

Expected value for supported

Error message

Expected value for supported ${quote(key)} to be a boolean, got ${typeof value} instead

What it means

Each entry in the `supported` map must be a boolean (true = feature is supported, false = polyfill needed). At lib/shared/common.ts:229 esbuild rejects non-boolean values with the key and the actual typeof, because the value is emitted verbatim as `--supported:key=true|false`.

Solutions

  1. Coerce each value to an actual boolean (e.g. value === 'true' or Boolean(value) as appropriate).
  2. Type your supported object as Record<string, boolean>.

Example fix

// before
await build({ entryPoints: ['app.ts'], supported: { 'async-await': 'true' } })

// after
await build({ entryPoints: ['app.ts'], supported: { 'async-await': true } })
Defensive patterns

Strategy: validation

Validate before calling

function coerceSupported(map) {
  if (!map) return map
  const out = {}
  for (const k of Object.keys(map)) {
    const v = map[k]
    out[k] = typeof v === 'boolean' ? v : (v === 'true' || v === 1)
  }
  return out
}
options.supported = coerceSupported(options.supported)

Type guard

function isSupportedMap(v): v is Record<string, boolean> {
  if (!v || typeof v !== 'object') return false
  return Object.values(v).every(x => typeof x === 'boolean')
}
if (options.supported && !isSupportedMap(options.supported)) {
  throw new Error('supported values must be booleans')
}

Prevention

When it happens

Trigger: Passing `supported: { 'async-await': 'true' }`, `{ 'async-await': 1 }`, or `{ 'async-await': null }`.

Common situations: Loading supported flags from JSON/env where booleans become strings or numbers; forwarding untyped UI input.

Related errors


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

Appendix: source

Thrown at lib/shared/common.ts:229

  if (jsxSideEffects) flags.push(`--jsx-side-effects`)

  if (define) {
    for (let key in define) {
      if (key.indexOf('=') >= 0) throw new Error(`Invalid define: ${key}`)
      flags.push(`--define:${key}=${validateStringValue(define[key], 'define', key)}`)
    }
  }
  if (logOverride) {
    for (let key in logOverride) {
      if (key.indexOf('=') >= 0) throw new Error(`Invalid log override: ${key}`)
      flags.push(`--log-override:${key}=${validateStringValue(logOverride[key], 'log override', key)}`)
    }
  }
  if (supported) {
    for (let key in supported) {
      if (key.indexOf('=') >= 0) throw new Error(`Invalid supported: ${key}`)
      const value = supported[key]
      if (typeof value !== 'boolean') throw new Error(`Expected value for supported ${quote(key)} to be a boolean, got ${typeof value} instead`)
      flags.push(`--supported:${key}=${value}`)
    }
  }
  if (pure) for (let fn of pure) flags.push(`--pure:${validateStringValue(fn, 'pure')}`)
  if (keepNames) flags.push(`--keep-names`)
}

function flagsForBuildOptions(
  callName: string,
  options: types.BuildOptions,
  isTTY: boolean,
  logLevelDefault: types.LogLevel,
  writeDefault: boolean,
): {
  entries: [string, string][],
  flags: string[],
  write: boolean,
  stdinContents: Uint8Array | null,

View on GitHub (pinned to f6058f8364)