evanw/esbuild · error · Error

Invalid banner file type

Error message

Invalid banner file type: ${type}

What it means

The `banner` option (build) is a map of file type to text, serialized as `--banner:TYPE=TEXT`. An '=' inside the TYPE breaks parsing, so esbuild rejects it at lib/shared/common.ts:322. Valid types are typically 'js' and 'css'.

Solutions

  1. Use a valid file type key without '=' (commonly 'js' or 'css').
  2. Strip '=' from generated keys.

Example fix

// before
await build({ entryPoints: ['app.ts'], banner: { 'js=app': '/* header */' } })

// after
await build({ entryPoints: ['app.ts'], banner: { js: '/* header */' } })
Defensive patterns

Strategy: validation

Validate before calling

const VALID_BANNER_TYPES = new Set(['js', 'css'])
function assertBannerKeys(map) {
  for (const k of Object.keys(map ?? {})) {
    if (!VALID_BANNER_TYPES.has(k)) throw new Error(`banner key must be 'js' or 'css', got ${k}`)
  }
}
assertBannerKeys(options.banner)

Prevention

When it happens

Trigger: Passing `banner: { 'js=x': '...' }` or any banner key containing '='.

Common situations: Typo or generated key; confusion about which key to use (should be 'js'/'css').

Related errors


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

Appendix: source

Thrown at lib/shared/common.ts:322

  if (tsconfig) flags.push(`--tsconfig=${tsconfig}`)
  if (packages) flags.push(`--packages=${packages}`)
  if (resolveExtensions) flags.push(`--resolve-extensions=${validateAndJoinStringArray(resolveExtensions, 'resolve extension')}`)
  if (publicPath) flags.push(`--public-path=${publicPath}`)
  if (entryNames) flags.push(`--entry-names=${entryNames}`)
  if (chunkNames) flags.push(`--chunk-names=${chunkNames}`)
  if (assetNames) flags.push(`--asset-names=${assetNames}`)
  if (mainFields) flags.push(`--main-fields=${validateAndJoinStringArray(mainFields, 'main field')}`)
  if (conditions) flags.push(`--conditions=${validateAndJoinStringArray(conditions, 'condition')}`)
  if (external) for (let name of external) flags.push(`--external:${validateStringValue(name, 'external')}`)
  if (alias) {
    for (let old in alias) {
      if (old.indexOf('=') >= 0) throw new Error(`Invalid package name in alias: ${old}`)
      flags.push(`--alias:${old}=${validateStringValue(alias[old], 'alias', old)}`)
    }
  }
  if (banner) {
    for (let type in banner) {
      if (type.indexOf('=') >= 0) throw new Error(`Invalid banner file type: ${type}`)
      flags.push(`--banner:${type}=${validateStringValue(banner[type], 'banner', type)}`)
    }
  }
  if (footer) {
    for (let type in footer) {
      if (type.indexOf('=') >= 0) throw new Error(`Invalid footer file type: ${type}`)
      flags.push(`--footer:${type}=${validateStringValue(footer[type], 'footer', type)}`)
    }
  }
  if (inject) for (let path of inject) flags.push(`--inject:${validateStringValue(path, 'inject')}`)
  if (loader) {
    for (let ext in loader) {
      if (ext.indexOf('=') >= 0) throw new Error(`Invalid loader extension: ${ext}`)
      flags.push(`--loader:${ext}=${validateStringValue(loader[ext], 'loader', ext)}`)
    }
  }
  if (outExtension) {
    for (let ext in outExtension) {

View on GitHub (pinned to f6058f8364)