evanw/esbuild · error · Error
Expected value for to be a string, got instead
Error message
Expected value for ${what}${key !== void 0 ? ' ' + quote(key) : ''} to be a string, got ${typeof value} instead What it means
validateStringValue() at lib/shared/common.ts:140 guards every option value that becomes a `--flag:key=value` CLI token (define, logOverride, alias, banner, footer, loader, outExtension, external, inject, pure, drop, entryPoint values). Each such value must be a JS string; otherwise esbuild throws naming the context (`what`), the key, and the actual typeof it received.
Solutions
- Convert the value to a string (e.g. String(value), value.toString(), or regex .source).
- For define/replace values that must be string literals in output, wrap in quotes: `"'production'"`.
- Type the map as Record<string, string> in your own config so non-strings are caught upstream.
Example fix
// before
await build({ entryPoints: ['app.ts'], define: { NODE_ENV: true } })
// after
await build({ entryPoints: ['app.ts'], define: { NODE_ENV: 'true' } }) Defensive patterns
Strategy: type-guard
Validate before calling
function assertStringValues(map, name) {
if (!map) return map
for (const k of Object.keys(map)) {
if (typeof map[k] !== 'string') {
throw new Error(`${name}[${k}] must be a string, got ${typeof map[k]}`)
}
}
return map
}
assertStringValues(options.define, 'define')
assertStringValues(options.loader, 'loader') Type guard
function isStringRecord(v): v is Record<string, string> {
if (!v || typeof v !== 'object') return false
return Object.values(v).every(x => typeof x === 'string')
}
if (options.define && !isStringRecord(options.define)) {
throw new Error('define values must all be strings')
} Prevention
- Type define/loader/alias/banner/footer/outExtension maps as Record<string, string>.
- For define values that should be string literals, wrap them in extra quotes.
- Coerce regex/function sources with .toString() or .source before placing them in these maps.
When it happens
Trigger: Passing `define: { NODE_ENV: true }`, `loader: { '.css': 1 }`, `external: [/^foo/]`, `pure: [function f(){}]`, or `entryPoints: { app: 42 }`.
Common situations: Using a native JS value (boolean, number, regex, function) instead of its string form; loading config from JSON with mixed types; forwarding untyped user input into these keyed maps.
Related errors
- Expected value for supported
- Invalid
- must be
- Expected in mangle cache to map to either a string or false
- Invalid banner file type
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/9143ed2431a97ded.
Report an issue: GitHub.
Appendix: source
Thrown at lib/shared/common.ts:142
type CommonOptions = types.BuildOptions | types.TransformOptions
function pushLogFlags(flags: string[], options: CommonOptions, keys: OptionKeys, isTTY: boolean, logLevelDefault: types.LogLevel): void {
let color = getFlag(options, keys, 'color', mustBeBoolean)
let logLevel = getFlag(options, keys, 'logLevel', mustBeString)
let logLimit = getFlag(options, keys, 'logLimit', mustBeInteger)
let logStyle = getFlag(options, keys, 'logStyle', mustBeString)
if (color !== void 0) flags.push(`--color=${color}`)
else if (isTTY) flags.push(`--color=true`); // This is needed to fix "execFileSync" which buffers stderr
flags.push(`--log-level=${logLevel || logLevelDefault}`)
flags.push(`--log-limit=${logLimit || 0}`)
if (logStyle) flags.push(`--log-style=${logStyle}`)
}
function validateStringValue(value: unknown, what: string, key?: string): string {
if (typeof value !== 'string') {
throw new Error(`Expected value for ${what}${key !== void 0 ? ' ' + quote(key) : ''} to be a string, got ${typeof value} instead`)
}
return value
}
function pushCommonFlags(flags: string[], options: CommonOptions, keys: OptionKeys): void {
let legalComments = getFlag(options, keys, 'legalComments', mustBeString)
let sourceRoot = getFlag(options, keys, 'sourceRoot', mustBeString)
let sourcesContent = getFlag(options, keys, 'sourcesContent', mustBeBoolean)
let target = getFlag(options, keys, 'target', mustBeStringOrArrayOfStrings)
let format = getFlag(options, keys, 'format', mustBeString)
let globalName = getFlag(options, keys, 'globalName', mustBeString)
let mangleProps = getFlag(options, keys, 'mangleProps', mustBeRegExp)
let reserveProps = getFlag(options, keys, 'reserveProps', mustBeRegExp)
let mangleQuoted = getFlag(options, keys, 'mangleQuoted', mustBeBoolean)
let minify = getFlag(options, keys, 'minify', mustBeBoolean)
let minifySyntax = getFlag(options, keys, 'minifySyntax', mustBeBoolean)
let minifyWhitespace = getFlag(options, keys, 'minifyWhitespace', mustBeBoolean)
let minifyIdentifiers = getFlag(options, keys, 'minifyIdentifiers', mustBeBoolean)View on GitHub (pinned to f6058f8364)