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

  1. Remove the extra 'default' clause.
  2. If both branches are needed, convert one to an explicit 'case'.
  3. 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

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


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