evanw/esbuild · error · Error

Invalid option

Error message

Invalid option ${where}: ${quote(key)}

What it means

After all recognized options are read, checkForInvalidFlags() (lib/shared/common.ts:86) iterates the options object and rejects any property name it does not recognize. This deliberately turns silent typos and version-mismatched option names into a hard error so misconfiguration is never quietly ignored. The `where` string tells you which call's options object has the bad key.

Solutions

  1. Compare the offending key (quoted in the message) against esbuild's current option list and fix the spelling.
  2. If the option is real but from a newer esbuild, upgrade the esbuild package; if from an older one, remove/replace it.
  3. Strip unknown keys when forwarding arbitrary user config objects into esbuild.

Example fix

// before
await build({ enteryPoints: ['app.ts'], bundle: true })

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

Strategy: validation

Validate before calling

import type { BuildOptions } from 'esbuild'
const KNOWN_BUILD_KEYS = new Set([
  'entryPoints','bundle','outfile','outdir','format','target','platform','define',
  'loader','plugins','sourcemap','minify','external','alias',
  /* ...full list from esbuild docs */
])
function rejectUnknownKeys(opts: Record<string, unknown>, scope: string) {
  for (const k of Object.keys(opts)) {
    if (!KNOWN_BUILD_KEYS.has(k)) throw new Error(`Unknown ${scope} option: ${k}`)
  }
}
rejectUnknownKeys(opts, 'build')

Prevention

When it happens

Trigger: Passing a misspelled option (e.g. `enteryPoints`, `bundel`, `outpuFiles`), an option from a different esbuild version, or a stray property to build()/context()/transform()/initialize()/stdin/watch()/serve()/cors/entry-point objects.

Common situations: Typos; using a newer option on an older esbuild install (or vice versa); leftover keys copied from a different bundler's config (webpack/rollup); IDE autocomplete inserting the wrong name.

Related errors


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

Appendix: source

Thrown at lib/shared/common.ts:89

let mustBeStringOrURL = (value: string | URL | undefined): string | null =>
  typeof value === 'string' || value instanceof URL ? null : 'a string or a URL'

type OptionKeys = { [key: string]: boolean }

function getFlag<T, K extends (keyof T & string)>(object: T, keys: OptionKeys, key: K, mustBeFn: (value: T[K]) => string | null): T[K] | undefined {
  let value = object[key]
  keys[key + ''] = true
  if (value === undefined) return undefined
  let mustBe = mustBeFn(value)
  if (mustBe !== null) throw new Error(`${quote(key)} must be ${mustBe}`)
  return value
}

function checkForInvalidFlags(object: Object, keys: OptionKeys, where: string): void {
  for (let key in object) {
    if (!(key in keys)) {
      throw new Error(`Invalid option ${where}: ${quote(key)}`)
    }
  }
}

export function validateInitializeOptions(options: types.InitializeOptions): types.InitializeOptions {
  let keys: OptionKeys = Object.create(null)
  let wasmURL = getFlag(options, keys, 'wasmURL', mustBeStringOrURL)
  let wasmModule = getFlag(options, keys, 'wasmModule', mustBeWebAssemblyModule)
  let worker = getFlag(options, keys, 'worker', mustBeBoolean)
  checkForInvalidFlags(options, keys, 'in initialize() call')
  return {
    wasmURL,
    wasmModule,
    worker,
  }
}

type MangleCache = Record<string, string | false>

View on GitHub (pinned to f6058f8364)