{"record":{"id":"29520bb2232245ca","repo":"karatelabs/karate","slug":"continue-label-does-not-name-a-loop-target","errorCode":null,"errorMessage":"continue label does not name a loop: ${target}","messagePattern":"continue label does not name a loop: (.+?)","errorType":"exception","errorClass":"ParserException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/parser/JsParser.java","lineNumber":425,"sourceCode":"            // §15.7.1 makes a static initialization block a boundary of the same kind\n            // as a function body: nothing inside it may name a label outside it.\n            case FN_EXPR, FN_ARROW_EXPR, CLASS_STATIC_BLOCK -> {\n                return null;\n            }\n            case BREAK_STMT -> {\n                String target = labelReference(node);\n                if (target != null && !Label.contains(labels, target, false)) {\n                    throw new ParserException(\"break references an undefined label: \" + target);\n                }\n            }\n            case CONTINUE_STMT -> {\n                String target = labelReference(node);\n                if (target != null) {\n                    if (!Label.contains(labels, target, false)) {\n                        throw new ParserException(\"continue references an undefined label: \" + target);\n                    }\n                    if (!Label.contains(labels, target, true)) {\n                        throw new ParserException(\"continue label does not name a loop: \" + target);\n                    }\n                }\n            }\n            default -> {\n            }\n        }\n        return labels;\n    }\n\n    /** The label named by a {@code break} / {@code continue}, or null when it has none —\n     *  children are [keyword] or [keyword, label]. */\n    private static String labelReference(Node node) {\n        return node.size() > 1 ? node.get(1).getText() : null;\n    }\n\n    /** True if the labelled item — after peeling any stacked labels, since {@code a: b: for}\n     *  makes both names loop labels — is an iteration statement. */\n    private static boolean labelsIterationStatement(Node labelled) {","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/parser/JsParser.java#L407-L443","documentation":"`continue` may only target labels that name iteration statements (loops). After confirming the label exists in scope, labelNodeChecks re-checks with the iteration flag (Label.contains(labels, target, true)); if the label names a non-loop labeled statement (e.g. a labeled block or switch), this early error is thrown.","triggerScenarios":"`continue blockLabel;` where blockLabel labels a plain block `{ }`, an `if`, or a `switch` rather than a for/while/do loop — e.g. `blk: { continue blk; }`.","commonSituations":"Changing a loop into a labeled block while keeping a continue pointing at it; misunderstanding that `continue` (unlike `break`) cannot target arbitrary labeled statements.","solutions":["Change `continue label;` to `break label;` if the target is a non-loop labeled statement and you want to exit it","Retarget continue to a label that names an enclosing loop","Restructure the non-loop labeled statement into a loop if iteration semantics are intended"],"exampleFix":"// before\nblk: { continue blk; }\n// after\nblk: { break blk; }","handlingStrategy":"validation","validationCode":"// Verify continue targets label loops, not blocks/switch:\nconst cont = [...src.matchAll(/continue\\s+([A-Za-z_$][\\w$]*)/g)].map(m=>m[1]);\nconst loopLabels = new Set([...src.matchAll(/([A-Za-z_$][\\w$]*):\\s*(?:for|while|do)\\b/g)].map(m=>m[1]));\nconst bad = cont.filter(t => !loopLabels.has(t));","typeGuard":null,"tryCatchPattern":"try { eval(js); } catch (e) { if (String(e).includes('continue label does not name a loop')) { /* switch to `break label` or retarget a loop label */ } throw e; }","preventionTips":["Only label loops if you plan to `continue` them; use `break` for blocks","Convert labeled blocks to loops when iteration semantics are needed","Review label usage after converting loops to plain blocks"],"tags":["javascript","parser","labels","continue"],"backgroundTag":"undefined-label-reference","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"}