karatelabs/karate · error · ParserException

more than one `default` clause in a switch

Error message

more than one `default` clause in a switch

What it means

A `switch` statement may contain at most one `default` clause; more than one is an early error. The Karate JS parser scans SWITCH_STMT children for multiple DEFAULT_BLOCK nodes and throws. Remove or merge the extra `default`.

Solutions

  1. Delete the redundant `default:` clause.
  2. Merge the bodies of both `default` clauses into a single one.
  3. Convert one `default` into an explicit `case` matching the intended value.

Example fix

// before
switch (x) { case 1: a(); break; default: b(); break; default: c(); }
// after
switch (x) { case 1: a(); break; default: b(); c(); }
Defensive patterns

Strategy: validation

Validate before calling

// count default clauses in a switch body string
function singleDefault(src) { return (src.match(/\bdefault\s*:/g) || []).length <= 1; }

Try / catch

try { karate.eval(src); } catch (e) { if (String(e).includes("more than one `default` clause")) { /* merge/remove defaults */ } }

Prevention

When it happens

Trigger: Parsing a switch statement whose case list contains two or more `default:` clauses, detected in earlyErrorNodeChecks.

Common situations: Merging branches from two code paths during refactoring; copy-paste duplicating a switch arm; adding a new fallback without noticing an existing one.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/3a3b162d0e046a62. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/parser/JsParser.java:572

            // A LexicalDeclaration (let/const) and a ClassDeclaration are likewise
            // Declarations, not Statements, and — unlike FunctionDeclaration — have no
            // Annex B carve-out for ANY clause, so they are illegal as the body of an
            // `if`/`else` clause too (§13.6/§14.x). The `for`-init `let` is a direct
            // FOR_STMT child, not a STATEMENT, so it is correctly ignored.
            case FOR_STMT, WHILE_STMT, DO_WHILE_STMT -> {
                checkNoFunctionDeclarationBody(node, "a loop");
                checkNoLexicalOrClassDeclarationBody(node, "a loop");
            }
            case IF_STMT -> checkNoLexicalOrClassDeclarationBody(node, "an `if`/`else` clause");
            // CaseBlock has at most one DefaultClause (§14.12.1). The grammar accepts
            // `default` anywhere among the cases, so the count is checked here.
            case SWITCH_STMT -> {
                boolean seen = false;
                for (int i = 0, n = node.size(); i < n; i++) {
                    Node child = node.get(i);
                    if (!child.isToken() && child.type == NodeType.DEFAULT_BLOCK) {
                        if (seen) {
                            throw new ParserException("more than one `default` clause in a switch");
                        }
                        seen = true;
                    }
                }
            }
            // LabelledItem is a Statement or a FunctionDeclaration; the latter is a strict-mode
            // early error with only an Annex B.3.1 sloppy carve-out. karate-js rejects it in both
            // modes: the hoisting a bare `function f(){}` gets does not reach through the
            // LABELLED_STMT wrapper, so accepting it would bind `f` later than the reader expects.
            // let/const/class have no carve-out at all.
            case LABELLED_STMT -> {
                checkNoFunctionDeclarationBody(node, "a labelled statement");
                checkNoLexicalOrClassDeclarationBody(node, "a labelled statement");
            }
            default -> {
            }
        }
    }

View on GitHub (pinned to a22eb90246)