evanw/esbuild · error · LexerPanic
Multiple default clauses are not allowed
Error message
Multiple default clauses are not allowed
What it means
A switch statement may contain at most one 'default' clause. esbuild tracks 'foundDefault' and, on encountering a second 'default' (js_parser.go:7609), reports 'Multiple default clauses are not allowed'.
Source
Thrown at internal/js_parser/js_parser.go:7611
p.pushScopeForParsePass(js_ast.ScopeBlock, bodyLoc)
defer p.popScope()
p.lexer.Expect(js_lexer.TOpenBrace)
cases := []js_ast.Case{}
foundDefault := false
switchScopeStart := len(p.scopesInOrder)
var caseScopeMap map[*js_ast.Scope]struct{}
for p.lexer.Token != js_lexer.TCloseBrace {
var value js_ast.Expr
body := []js_ast.Stmt{}
caseLoc := p.saveExprCommentsHere()
caseScopeStart := len(p.scopesInOrder)
if p.lexer.Token == js_lexer.TDefault {
if foundDefault {
p.log.AddError(&p.tracker, p.lexer.Range(), "Multiple default clauses are not allowed")
panic(js_lexer.LexerPanic{})
}
foundDefault = true
p.lexer.Next()
p.lexer.Expect(js_lexer.TColon)
} else {
p.lexer.Expect(js_lexer.TCase)
value = p.parseExpr(js_ast.LLowest)
p.lexer.Expect(js_lexer.TColon)
}
// Keep track of any scopes created by case values. This can happen if
// code uses anonymous functions inside a case value. For example:
//
// switch (x) {
// case y.map(z => -z).join(':'):
// return y
// }
//View on GitHub (pinned to f6058f8364)
Solutions
- Remove the extra 'default' clause.
- If both branches are needed, convert one to an explicit 'case'.
- Merge the bodies of the duplicate defaults into a single clause.
Example fix
// before
switch (x) {
default: a();
default: b();
}
// after
switch (x) {
default: a();
} Defensive patterns
Strategy: validation
Validate before calling
import "github.com/evanw/esbuild/pkg/api"
res := api.Transform(src, api.TransformOptions{Loader: api.LoaderJS})
for _, m := range res.Errors {
if strings.Contains(m.Text, "Multiple default clauses") {
// two 'default:' in one switch; m.Location marks the second
}
} Type guard
// Count 'default' clauses per switch block; flag >1.
func switchHasMultipleDefaults(src string) bool {
depth, defaults := 0, 0
for i := 0; i < len(src); i++ {
switch src[i] {
case '{': depth++
case '}': if depth > 0 { depth--; if depth == 0 { if defaults > 1 { return true }; defaults = 0 } }
}
if depth > 0 && strings.HasPrefix(src[i:], "default") { defaults++ }
}
return false
} Prevention
- Merge duplicated default branches into one.
- Use eslint/tsc to flag duplicate switch defaults.
- When merging switch bodies, deduplicate default clauses.
When it happens
Trigger: switch (x) { default: a(); default: b(); } — two default clauses in one switch body.
Common situations: Merging two switch bodies; copy-paste duplication; faulty code generation.
Related errors
- Unexpected newline before "=>"
- For loop initializers cannot start with "async of"
- Invalid binding pattern
- Unexpected ":"
- Unexpected "..."
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/dcf49ca353d8d60d.
Report an issue: GitHub.