evanw/esbuild · error · Error

Invalid

Error message

Invalid ${what}: ${value}

What it means

esbuild serializes several array-valued options (target, dropLabels, absPaths, resolveExtensions, mainFields, conditions) into a single comma-delimited CLI flag via validateAndJoinStringArray(). A comma inside any element would corrupt that delimited encoding, so such values are rejected at lib/shared/common.ts:16. Each element must also individually be a valid string (validated first).

Solutions

  1. Split the offending element into separate array entries (e.g. ['es2015','esnext'] not ['es2015,esnext']).
  2. If the value legitimately needs a comma (rare), pick a different representation supported by the option.
  3. Sanitize generated config by splitting on ',' before passing.

Example fix

// before
await build({ target: ['es2015,esnext'], entryPoints: ['app.ts'] })

// after
await build({ target: ['es2015', 'esnext'], entryPoints: ['app.ts'] })
Defensive patterns

Strategy: validation

Validate before calling

function assertNoCommas(arr, name) {
  for (const v of arr) {
    if (typeof v === 'string' && v.includes(',')) {
      throw new Error(`${name} element must not contain a comma: ${v}`)
    }
  }
  return arr
}
// use before build():
assertNoCommas(options.target ?? [], 'target')
assertNoCommas(options.mainFields ?? [], 'mainFields')

Prevention

When it happens

Trigger: Passing `target: ['es2015,esnext']`, `mainFields: ['main,browser']`, `conditions: ['import,default']`, or any of the joined-array options with an element whose string value contains a ',' character.

Common situations: Typing a comma-separated list as one array element instead of separate elements; generating config by joining strings with ','; copy-pasting a comma-separated value from docs into an array literal.

Related errors


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

Appendix: source

Thrown at lib/shared/common.ts:16

import type * as types from "./types"
import * as protocol from "./stdio_protocol"
import { JSON_parse } from "./uint8array_json_parser"

declare const ESBUILD_VERSION: string

const quote: (x: string) => string = JSON.stringify

const buildLogLevelDefault = 'warning'
const transformLogLevelDefault = 'silent'

function validateAndJoinStringArray(values: string[], what: string): string {
  const toJoin: string[] = []
  for (const value of values) {
    validateStringValue(value, what)
    if (value.indexOf(',') >= 0) throw new Error(`Invalid ${what}: ${value}`)
    toJoin.push(value)
  }
  return toJoin.join(',')
}

let canBeAnything = () => null

let mustBeBoolean = (value: boolean | undefined): string | null =>
  typeof value === 'boolean' ? null : 'a boolean'

let mustBeString = (value: string | undefined): string | null =>
  typeof value === 'string' ? null : 'a string'

let mustBeRegExp = (value: RegExp | undefined): string | null =>
  value instanceof RegExp ? null : 'a RegExp object'

let mustBeInteger = (value: number | undefined): string | null =>
  typeof value === 'number' && value === (value | 0) ? null : 'an integer'

View on GitHub (pinned to f6058f8364)