{"record":{"id":"a127e48bfde0e535","repo":"karatelabs/karate","slug":"too-much-recursion","errorCode":null,"errorMessage":"too much recursion","messagePattern":"too much recursion","errorType":"exception","errorClass":"io.karatelabs.parser.ParserException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/parser/BaseParser.java","lineNumber":211,"sourceCode":"            return true;\n        }\n        error(token);\n        return errorRecoveryEnabled; // Continue if recovering, never reached otherwise\n    }\n\n    /**\n     * Exit that tolerates incomplete nodes.\n     * Even if the node is incomplete, it is added to the parent.\n     */\n    protected boolean exitSoft() {\n        return exit(true, false, Shift.NONE);\n    }\n\n    // ========== End Error Recovery Methods ==========\n\n    protected void enter(NodeType type) {\n        if (stackPointer >= MAX_DEPTH) {\n            throw new ParserException(\"too much recursion\");\n        }\n        positionStack[stackPointer] = position;\n        nodeStack[stackPointer] = new Node(type);\n        stackPointer++;\n    }\n\n    // Single-token overload - avoids array allocation\n    protected boolean enter(NodeType type, TokenType token) {\n        if (peek() != token) {\n            return false;\n        }\n        if (stackPointer >= MAX_DEPTH) {\n            throw new ParserException(\"too much recursion\");\n        }\n        positionStack[stackPointer] = position;\n        nodeStack[stackPointer] = new Node(type);\n        stackPointer++;\n        consumeNext();","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/parser/BaseParser.java#L193-L229","documentation":"enter(NodeType) pushes a new parse-frame onto a fixed-depth stack (MAX_DEPTH = 128). When the parser's recursive-descent nesting exceeds that limit it throws ParserException(\"too much recursion\") instead of overflowing the JVM stack, protecting against pathological nesting in the parsed source.","triggerScenarios":"Parsing source with deeply nested expressions/structures — e.g. hundreds of nested parentheses, a huge chained expression, machine-generated or minified JSON-in-JS with extreme nesting.","commonSituations":"Embedding very large minified JS payloads or auto-generated scripts in a Karate feature; deeply nested array/object literals in inline scripts.","solutions":["Reduce nesting: split the expression into intermediate variables or multiple steps.","Pretty-print/reformat minified code — nesting depth stays the same, so refactor deeply nested literals into sequential statements.","If the input is legitimately deep, load it as data (JSON file) rather than embedding it as a JS literal."],"exampleFix":"// before\nvar x = [[[[[ ... 200 levels ... ]]]]];\n// after\nvar part1 = [[ ... ]];\nvar part2 = [[ ... ]];\nvar x = part1.concat(part2);","handlingStrategy":"validation","validationCode":"// Bound nesting depth before eval (simple heuristic)\nint depth = 0, max = 0;\nfor (char c : script.toCharArray()) {\n    if (c=='('||c=='['||c=='{') depth = ++max > depth ? max : depth;\n    if (c==')'||c==']'||c=='}') depth--;\n}\nif (max > 100) throw new IllegalArgumentException(\"script nesting too deep for parser (max 128)\");","typeGuard":null,"tryCatchPattern":"try {\n    return karate.eval(script);\n} catch (ParserException e) {\n    if (\"too much recursion\".equals(e.getMessage())) {\n        throw new IllegalArgumentException(\"script exceeds parser nesting depth (128); flatten the expression\", e);\n    }\n    throw e;\n}","preventionTips":["Never embed huge minified or machine-generated JS literals; pass data via JSON files or variables.","Split deeply nested expressions into intermediate variables.","Precheck generated scripts for nesting depth before eval.","Keep binary payloads as byte data, not JS source."],"tags":["parser","recursion","stack-overflow","javascript"],"backgroundTag":"too-much-recursion","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"}