evanw/esbuild · critical

Invalid packages

Error message

Invalid packages

What it means

A panic raised by validateExternalPackages when the Packages value is not PackagesDefault, PackagesBundle, or PackagesExternal. Internal invariant reachable only via Go-API misuse constructing an out-of-range Packages value.

Source

Thrown at pkg/api/api_impl.go:226

func validateASCIIOnly(value Charset) bool {
	switch value {
	case CharsetDefault, CharsetASCII:
		return true
	case CharsetUTF8:
		return false
	default:
		panic("Invalid charset")
	}
}

func validateExternalPackages(value Packages) bool {
	switch value {
	case PackagesDefault, PackagesBundle:
		return false
	case PackagesExternal:
		return true
	default:
		panic("Invalid packages")
	}
}

func validateTreeShaking(value TreeShaking, bundle bool, format Format) bool {
	switch value {
	case TreeShakingDefault:
		// If we're in an IIFE then there's no way to concatenate additional code
		// to the end of our output so we assume tree shaking is safe. And when
		// bundling we assume that tree shaking is safe because if you want to add
		// code to the bundle, you should be doing that by including it in the
		// bundle instead of concatenating it afterward, so we also assume tree
		// shaking is safe then. Otherwise we assume tree shaking is not safe.
		return bundle || format == FormatIIFE
	case TreeShakingFalse:
		return false
	case TreeShakingTrue:
		return true
	default:

View on GitHub (pinned to 6ff1d8b0d8)

Solutions

  1. Use only PackagesDefault, PackagesBundle, or PackagesExternal.
  2. Validate deserialized values against an allowlist.
  3. Do not cast integers to Packages.
  4. Pin a single esbuild version.

Example fix

// before
opts.Packages = api.Packages(5)

// after
opts.Packages = api.PackagesExternal
Defensive patterns

Strategy: type-guard

Validate before calling

func validPackages(p api.Packages) bool {
  switch p {
  case api.PackagesDefault, api.PackagesBundle, api.PackagesExternal:
    return true
  }
  return false
}

Type guard

type Packages = 'bundle' | 'external'
function isPackages(v: unknown): v is Packages {
  return v === 'bundle' || v === 'external'
}

Prevention

When it happens

Trigger: Go API: BuildOptions.Packages = Packages(5). The JS API's Packages option ('bundle' | 'external') maps to valid constants and cannot trigger this panic.

Common situations: Reflective config decoding; fork ordinal drift; unsafe casts.

Related errors


AI-assisted analysis of evanw/esbuild@6ff1d8b0d8 (2026-08-03). Data as JSON: /data/errors/9cc032194d021b02.json. Report an issue: GitHub.