{"record":{"id":"11bba23a504afd02","repo":"karatelabs/karate","slug":"unary-expression-cannot-be-the-base-of-wrap-it-in","errorCode":null,"errorMessage":"unary expression cannot be the base of '**'; wrap it in parentheses","messagePattern":"unary expression cannot be the base of '\\*\\*'; wrap it in parentheses","errorType":"exception","errorClass":"ParserException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/parser/JsParser.java","lineNumber":514,"sourceCode":"                    TokenType op = node.size() > 1 && node.get(1).isToken() ? node.get(1).token.type : null;\n                    boolean noCallCarveOut = op == PIPE_PIPE_EQ || op == AMP_AMP_EQ || op == QUES_QUES_EQ;\n                    checkSimpleAssignmentTarget(lhs, \"assignment target\", noCallCarveOut);\n                }\n            }\n            case MATH_EXP_EXPR -> {\n                // §13.6: the base of `**` must be an UpdateExpression — an\n                // unparenthesized unary (-x, !x, ~x, +x, void x, typeof x,\n                // delete x.y, await x) is a SyntaxError; ++x / --x are legal.\n                Node base = stripExprWrappers(node.size() > 0 ? node.getFirst() : null);\n                if (base != null) {\n                    boolean unaryBase = switch (base.type) {\n                        case DELETE_EXPR, TYPEOF_EXPR, UNARY_EXPR, AWAIT_EXPR -> true;\n                        case MATH_PRE_EXPR -> base.size() > 0 && base.getFirst().isToken()\n                                && (base.getFirst().token.type == PLUS || base.getFirst().token.type == MINUS);\n                        default -> false;\n                    };\n                    if (unaryBase) {\n                        throw new ParserException(\"unary expression cannot be the base of '**'; wrap it in parentheses\");\n                    }\n                }\n            }\n            case MATH_POST_EXPR -> {\n                // children: [operand, ++/--]\n                if (node.size() > 0) {\n                    Node operand = node.getFirst();\n                    if (sawOptionalChain && subtreeContainsOptionalChain(operand)) {\n                        throw new ParserException(\"optional chain cannot be the operand of postfix ++/--\");\n                    }\n                    checkSimpleAssignmentTarget(operand, \"operand of postfix update\", false);\n                }\n            }\n            case MATH_PRE_EXPR -> {\n                // children: [op, operand] — only ++/-- need a valid update target;\n                // unary +/- have no assignment side and parse the same shape.\n                if (node.size() > 1) {\n                    Node op = node.getFirst();","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/parser/JsParser.java#L496-L532","documentation":"The exponentiation operator `**` forbids a unary expression as its left operand (`-a ** 2` is an early error in JS to avoid ambiguity with `-(a ** 2)`). The Karate JS parser throws this when the base of a `**` expression is a unary/typeof/delete/await/minus-prefixed expression. Wrap the operand in parentheses to state intent.","triggerScenarios":"Parsing expressions like `-x ** 2`, `+y ** 2`, `typeof a ** b`, `await p ** 2`, `delete o.k ** 2`, detected in earlyErrorNodeChecks for MATH_EXPR (power) nodes with a unary base.","commonSituations":"Porting math code like `-x ** 2` from Python (where it means `(-x) ** 2`) into JS; writing physics formulas with negated bases; code written by authors expecting C-like unary precedence.","solutions":["Add parentheses: `(-x) ** 2` if you want the negated base, or `-(x ** 2)` if you want negation of the power.","For `await`, use `(await p) ** 2`.","For `typeof`/`delete` bases, restructure — they rarely make sense as exponent bases."],"exampleFix":"// before\nlet area = -r ** 2;\n// after\nlet area = (-r) ** 2; // or -(r ** 2)","handlingStrategy":"validation","validationCode":"// flag unary bases under **\nfunction hasUnaryBase(src) { return /(^|[\\s(])[+-]\\s*[\\w$.]+\\s*\\*\\*/.test(src); }","typeGuard":null,"tryCatchPattern":"try { karate.eval(expr); } catch (e) { if (String(e).includes(\"cannot be the base of '**'\")) { /* add parentheses */ } }","preventionTips":["Always parenthesize the base of `**` when it involves unary operators.","Remember `-x ** 2` is illegal in JS even though `-x * x` is fine.","Prefer `Math.pow(x, 2)` for negated bases to avoid precedence confusion."],"tags":["javascript","parser","syntax-error","exponentiation"],"backgroundTag":"javascript-syntax-error","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"}