{"record":{"id":"44460cb5d2f8bc3e","repo":"karatelabs/karate","slug":"continue-may-not-cross-a-class-static-initialization-block","errorCode":null,"errorMessage":"'continue' may not cross a class static initialization block","messagePattern":"'continue' may not cross a class static initialization block","errorType":"exception","errorClass":"ParserException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/parser/JsParser.java","lineNumber":705,"sourceCode":"                prev = type;\n                continue;\n            }\n            prev = null;\n            int childFlags = flags;\n            switch (child.type) {\n                case RETURN_STMT -> {\n                    if ((flags & SB_FN) == 0) {\n                        throw new ParserException(\"'return' is not allowed in a class static initialization block\");\n                    }\n                }\n                case BREAK_STMT -> {\n                    if ((flags & (SB_FN | SB_LOOP | SB_SWITCH)) == 0 && child.size() == 1) {\n                        throw new ParserException(\"'break' may not cross a class static initialization block\");\n                    }\n                }\n                case CONTINUE_STMT -> {\n                    if ((flags & (SB_FN | SB_LOOP)) == 0 && child.size() == 1) {\n                        throw new ParserException(\"'continue' may not cross a class static initialization block\");\n                    }\n                }\n                case FOR_STMT, WHILE_STMT, DO_WHILE_STMT -> childFlags |= SB_LOOP;\n                case SWITCH_STMT -> childFlags |= SB_SWITCH;\n                case FN_EXPR, FN_ARROW_EXPR -> childFlags |= SB_FN;\n                default -> {\n                }\n            }\n            // A function's parameters are [~Await] along with its body; an arrow's are\n            // not — only the body (always its last child) leaves the reserved region.\n            if (node.type == NodeType.FN_EXPR\n                    || (node.type == NodeType.FN_ARROW_EXPR && i == last)) {\n                childFlags |= SB_AWAIT_OK;\n            }\n            checkStaticBlockBody(child, childFlags);\n        }\n    }\n","sourceCodeStart":687,"sourceCodeEnd":723,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/parser/JsParser.java#L687-L723","documentation":"Karate's embedded JS parser validates class static initialization block bodies against the ECMAScript grammar. A bare `continue` statement is only legal inside a loop, and a static block is not a loop; the check is skipped when the `continue` is nested inside a function or an enclosing loop (SB_FN / SB_LOOP flags). The parser throws this at parse time rather than producing silently invalid semantics.","triggerScenarios":"Writing `class C { static { continue; } }` or any bare `continue` directly inside a `static { ... }` block that is not itself wrapped in a loop or function — e.g. `static { for(;;){} continue; }` at block top level. Evaluated when parsing Karate JS expressions or embedded JS scripts.","commonSituations":"Copy-pasting loop code into a static block during a refactor; porting code where a `continue`'s enclosing loop was removed or moved outside the static block; hand-writing class-based JS in Karate scenario expressions.","solutions":["Remove the bare `continue` from the static block top level — there is no loop to continue.","Wrap the logic in a loop (for/while) inside the static block if iteration semantics are intended.","Move the `continue` into a nested function only if the loop also lives inside that function; a `continue` cannot cross a function boundary either.","If the intent was to skip static initialization, restructure with an `if` guard instead of `continue`."],"exampleFix":"// before\nclass C {\n  static {\n    continue; // error\n  }\n}\n// after\nclass C {\n  static {\n    for (const x of items) {\n      if (skip(x)) continue; // legal: inside a loop\n    }\n  }\n}","handlingStrategy":"validation","validationCode":"// before evaluating a class body in Karate JS, scan for bare continue at static-block top level\nfunction staticBlockHasBareContinue(src) {\n  const m = src.match(/static\\s*\\{([\\s\\S]*?)\\}/);\n  return !!m && /(^|[^\\w$.])continue\\s*(;|\\}|$)/.test(m[1]);\n}\nif (staticBlockHasBareContinue(src)) throw new Error('remove bare continue from static block');","typeGuard":null,"tryCatchPattern":"try {\n  const result = karate.eval(jsSource);\n} catch (e) {\n  if (String(e.message).includes(\"may not cross a class static initialization block\")) {\n    // fix the script source: strip/repair the static block statement\n  } else throw e;\n}","preventionTips":["Never place break/continue at the top level of a static block.","Keep loop control statements inside the loop they control.","Prefer simple, side-effect-light static blocks; extract loops into functions.","Lint generated JS before passing it to karate.eval."],"tags":["javascript","parser","syntax-error","class-static-block"],"backgroundTag":"invalid-argument-value","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}