evanw/esbuild · critical
Invalid tree shaking
Error message
Invalid tree shaking
What it means
validateTreeShaking (pkg/api/api_impl.go:258) panics when TreeShaking is not TreeShakingDefault(0), TreeShakingFalse(1), or TreeShakingTrue(2). For TreeShakingDefault the function computes a value from `bundle` and `format` (true when bundling or IIFE; otherwise false to be safe with later concatenation); any other numeric value is undefined and aborts. Reached from validateBuildOptions.
Solutions
- Prefer api.TreeShakingDefault (lets esbuild pick based on bundle/format); or set api.TreeShakingTrue / api.TreeShakingFalse explicitly.
- Bounds-check decoded integers against 0..2 before casting.
- Serialize the option as a string and map to the constant at load.
- Realign wrapper and core esbuild versions.
Example fix
// before
opts := api.BuildOptions{TreeShaking: api.TreeShaking(7), Bundle: true}
// after
opts := api.BuildOptions{TreeShaking: api.TreeShakingDefault, Bundle: true} Defensive patterns
Strategy: validation
Validate before calling
func checkTreeShaking(t api.TreeShaking) error {
switch t {
case api.TreeShakingDefault, api.TreeShakingFalse, api.TreeShakingTrue:
return nil
}
return fmt.Errorf("invalid tree shaking %d (want 0..2)", uint8(t))
} Type guard
func isValidTreeShaking(t api.TreeShaking) bool {
switch t {
case api.TreeShakingDefault, api.TreeShakingFalse, api.TreeShakingTrue:
return true
}
return false
} Prevention
- Use TreeShakingDefault so esbuild picks based on bundle/format (safe with later concatenation).
- Store the option as a string and translate at load.
- Bounds-check decoded integers to 0..2.
- Re-vendor all consumers after an esbuild upgrade.
When it happens
Trigger: Passing a numeric TreeShaking from a cast, JSON-decoded struct, or inter-language bridge with mismatched ordinals. Fires during options construction, before scanning.
Common situations: Persisted configs that store tree-shaking as an int, version drift between a wrapper and core, or a typo such as `TreeShaking: api.TreeShakingBoth`.
Related errors
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/12a4beff3f8821d0.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/api/api_impl.go:258
}
}
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:
panic("Invalid tree shaking")
}
}
func validateLoader(value Loader) config.Loader {
switch value {
case LoaderBase64:
return config.LoaderBase64
case LoaderBinary:
return config.LoaderBinary
case LoaderCopy:
return config.LoaderCopy
case LoaderCSS:
return config.LoaderCSS
case LoaderDataURL:
return config.LoaderDataURL
case LoaderDefault:
return config.LoaderDefault
case LoaderEmpty:View on GitHub (pinned to f6058f8364)