evanw/esbuild · error · Error

Invalid define

Error message

Invalid define: ${key}

What it means

The `define` option is serialized as `--define:KEY=value`. An '=' character inside the KEY would break the CLI parser's key/value split, so esbuild rejects any define key containing '=' at lib/shared/common.ts:215. The value side may contain '=' freely.

Solutions

  1. Remove the '=' from the define key.
  2. If you intended 'key=value', put the value on the value side: define: { key: 'value' }.
  3. Sanitize generated keys by stripping/replacing '='.

Example fix

// before
await build({ entryPoints: ['app.ts'], define: { 'NODE_ENV=prod': '1' } })

// after
await build({ entryPoints: ['app.ts'], define: { NODE_ENV: 'prod' } })
Defensive patterns

Strategy: validation

Validate before calling

function assertKeysHaveNoEquals(map, name) {
  for (const k of Object.keys(map ?? {})) {
    if (k.includes('=')) throw new Error(`${name} key must not contain '=': ${k}`)
  }
}
assertKeysHaveNoEquals(options.define, 'define')

Prevention

When it happens

Trigger: Passing `define: { 'a=b': '1' }` or any define key whose identifier string contains an '='.

Common situations: Dynamically generated define keys (e.g. from env vars or templated strings) that accidentally include '='; mis-formatted 'key=value' pairs stuffed into the key position.

Related errors


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

Appendix: source

Thrown at lib/shared/common.ts:215

  if (treeShaking !== void 0) flags.push(`--tree-shaking=${treeShaking}`)
  if (ignoreAnnotations) flags.push(`--ignore-annotations`)
  if (drop) for (let what of drop) flags.push(`--drop:${validateStringValue(what, 'drop')}`)
  if (dropLabels) flags.push(`--drop-labels=${validateAndJoinStringArray(dropLabels, 'drop label')}`)
  if (absPaths) flags.push(`--abs-paths=${validateAndJoinStringArray(absPaths, 'abs paths')}`)
  if (mangleProps) flags.push(`--mangle-props=${jsRegExpToGoRegExp(mangleProps)}`)
  if (reserveProps) flags.push(`--reserve-props=${jsRegExpToGoRegExp(reserveProps)}`)
  if (mangleQuoted !== void 0) flags.push(`--mangle-quoted=${mangleQuoted}`)

  if (jsx) flags.push(`--jsx=${jsx}`)
  if (jsxFactory) flags.push(`--jsx-factory=${jsxFactory}`)
  if (jsxFragment) flags.push(`--jsx-fragment=${jsxFragment}`)
  if (jsxImportSource) flags.push(`--jsx-import-source=${jsxImportSource}`)
  if (jsxDev) flags.push(`--jsx-dev`)
  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')}`)

View on GitHub (pinned to f6058f8364)