evanw/esbuild · critical
Invalid engine name
Error message
Invalid engine name
What it means
convertEngineName (pkg/api/api_js_table.go:48) panics when an EngineName passed in BuildOptions.Engines[i].Name is not one of the 11 declared iota constants (EngineChrome, EngineDeno, EngineEdge, EngineFirefox, EngineHermes, EngineIE, EngineIOS, EngineNode, EngineOpera, EngineRhino, EngineSafari). The file is auto-generated by js_table.ts; the panic indicates the public enum and the generated switch are out of sync, or a caller injected an Engine with a numeric Name from outside the declared set.
Source
Thrown at pkg/api/api_js_table.go:48
return compat.Edge
case EngineFirefox:
return compat.Firefox
case EngineHermes:
return compat.Hermes
case EngineIE:
return compat.IE
case EngineIOS:
return compat.IOS
case EngineNode:
return compat.Node
case EngineOpera:
return compat.Opera
case EngineRhino:
return compat.Rhino
case EngineSafari:
return compat.Safari
default:
panic("Invalid engine name")
}
}
View on GitHub (pinned to f6058f8364)
Solutions
- Construct Engine values using only the declared api.Engine* constants (Chrome, Deno, Edge, Firefox, Hermes, IE, IOS, Node, Opera, Rhino, Safari).
- Bounds-check any externally supplied integer against 0..10 before casting to EngineName.
- Map engine names from strings at the application boundary and reject unknown ones explicitly.
- After adding/removing an engine, regenerate pkg/api/api_js_table.go from js_table.ts and rebuild everything that links the Go core.
Example fix
// before
engines := []api.Engine{{Name: api.EngineName(20), Version: "100"}}
opts := api.BuildOptions{Engines: engines}
// after
engines := []api.Engine{{Name: api.EngineNode, Version: "20"}}
opts := api.BuildOptions{Engines: engines} Defensive patterns
Strategy: validation
Validate before calling
func checkEngineName(n api.EngineName) error {
switch n {
case api.EngineChrome, api.EngineDeno, api.EngineEdge, api.EngineFirefox,
api.EngineHermes, api.EngineIE, api.EngineIOS, api.EngineNode,
api.EngineOpera, api.EngineRhino, api.EngineSafari:
return nil
}
return fmt.Errorf("invalid engine name %d (want 0..10)", uint8(n))
}
for i, e := range opts.Engines {
if err := checkEngineName(e.Name); err != nil { return fmt.Errorf("engines[%d]: %w", i, err) }
} Type guard
func isValidEngineName(n api.EngineName) bool {
switch n {
case api.EngineChrome, api.EngineDeno, api.EngineEdge, api.EngineFirefox,
api.EngineHermes, api.EngineIE, api.EngineIOS, api.EngineNode,
api.EngineOpera, api.EngineRhino, api.EngineSafari:
return true
}
return false
} Prevention
- Construct Engine values only with declared api.Engine* constants.
- Because api_js_table.go is auto-generated, regenerate it from js_table.ts whenever you add or reorder engines, then rebuild everything that links the core.
- Map engine names from strings at the application boundary and reject unknown ones.
- Bounds-check integers from inter-process sources to 0..10.
When it happens
Trigger: Constructing an Engine literal with `Name: api.EngineName(N)` for N outside 0..10, deserializing Engines from JSON where Name is a number, or running a generated bridge whose js_table.ts predates a renumbering/addition of an engine constant. Reached via validateFeatures when iterating Engines.
Common situations: Code generators or cgo bindings that hand-build Engine structs, version skew between the auto-generated table and a hand-edited wrapper, or attempting to add a new engine by writing an integer instead of extending the enum and regenerating the table.
Related errors
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/1fe226783003bf27.
Report an issue: GitHub.