karatelabs/karate · error · ParserException

'await' is a reserved word in a class static initialization…

Error message

'await' is a reserved word in a class static initialization block

What it means

Inside a class static initialization block, `await` is a reserved word and cannot be used as an identifier (the block is implicitly an async-like context). The Karate JS parser throws this when `await` appears in identifier position, except as a member name after `.` or `?.` (e.g. `x.await` is allowed). Rename the identifier.

Solutions

  1. Rename the identifier from `await` to something else (e.g. `awaitResult`, `aWait`).
  2. Access members via dot syntax (`obj.await`) which remains legal, instead of destructuring/shorthand using the bare word.
  3. Move the code out of the static block into a regular static method if the identifier cannot be renamed.

Example fix

// before
class C { static { let await = fetchCfg(); } }
// after
class C { static { let cfg = fetchCfg(); } }
Defensive patterns

Strategy: validation

Validate before calling

// flag `await` used as a bare identifier inside static block sources
function awaitSafe(src) { return !/(?<![\w$.])await(?![\w$])(?!\s*:)/.test(src.replace(/\.await|\?\.await/g, '')); }

Try / catch

try { karate.eval(blockSrc); } catch (e) { if (String(e).includes("'await' is a reserved word")) { /* rename identifier */ } }

Prevention

When it happens

Trigger: Parsing a class `static { ... }` block whose body uses `await` as a variable name or property shorthand (`{ await }`, `let await = ...`), detected by the static-block body walker with keepAwait member-access exemption.

Common situations: Code using `await` as a variable (legal in sloppy non-module scripts) being moved into a static block; minified/generated code that picked `await` as a name; upgrading class fields to static blocks during refactoring.

Related errors


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

Appendix: source

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

     *       check is on the token — skipping the positions where it is a property name
     *       rather than a reference.</li>
     * </ul>
     * {@code arguments} is equally illegal per spec but is not rejected here: telling a
     * reference from the many legal {@code x.arguments} / {@code {arguments: …}} spellings
     * costs more than the rule is worth.
     */
    private void checkStaticBlockBody(Node node, int flags) {
        boolean keepAwait = (flags & SB_AWAIT_OK) == 0 && !isPropertyNameHolder(node);
        int last = node.size() - 1;
        TokenType prev = null;
        for (int i = 0; i <= last; i++) {
            Node child = node.get(i);
            if (child.isToken()) {
                TokenType type = child.token.type;
                // `x.await` / `x?.await` name a member, they do not reference one
                if (keepAwait && type == IDENT && prev != DOT && prev != QUES_DOT
                        && isIdentText(child.token, "await")) {
                    throw new ParserException("'await' is a reserved word in a class static initialization block");
                }
                prev = type;
                continue;
            }
            prev = null;
            int childFlags = flags;
            switch (child.type) {
                case RETURN_STMT -> {
                    if ((flags & SB_FN) == 0) {
                        throw new ParserException("'return' is not allowed in a class static initialization block");
                    }
                }
                case BREAK_STMT -> {
                    if ((flags & (SB_FN | SB_LOOP | SB_SWITCH)) == 0 && child.size() == 1) {
                        throw new ParserException("'break' may not cross a class static initialization block");
                    }
                }
                case CONTINUE_STMT -> {

View on GitHub (pinned to a22eb90246)