{"record":{"id":"a03bb2e230e22927","repo":"karatelabs/karate","slug":"invalid-sitename-parenthesized-destructuring-pattern","errorCode":null,"errorMessage":"invalid ${siteName}: parenthesized destructuring pattern","messagePattern":"invalid (.+?): parenthesized destructuring pattern","errorType":"exception","errorClass":"ParserException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/parser/JsParser.java","lineNumber":1706,"sourceCode":"        // ObjectLiteral or ArrayLiteral does NOT refine to a destructuring pattern,\n        // so it becomes invalid; everything else falls through to the simple check.\n        while (n.type == NodeType.PAREN_EXPR) {\n            // PAREN_EXPR shape: [(, body, )]\n            Node body = n.size() >= 2 ? n.get(1) : null;\n            if (body == null) {\n                throw new ParserException(\"invalid \" + siteName);\n            }\n            if (body.type == NodeType.EXPR_LIST && body.size() != 1) {\n                throw new ParserException(\"invalid \" + siteName + \": comma expression\");\n            }\n            Node inner = stripExprWrappers(body);\n            if (inner == null) {\n                throw new ParserException(\"invalid \" + siteName);\n            }\n            if (inner.type == NodeType.LIT_EXPR && inner.size() >= 1) {\n                NodeType lit = inner.getFirst().type;\n                if (lit == NodeType.LIT_ARRAY || lit == NodeType.LIT_OBJECT) {\n                    throw new ParserException(\"invalid \" + siteName + \": parenthesized destructuring pattern\");\n                }\n            }\n            n = inner;\n        }\n        switch (n.type) {\n            case REF_EXPR -> {\n                // REF_EXPR is single-arg arrow `x => ...` when its first child is an\n                // FN_ARROW_EXPR rather than the IDENT token; that form is invalid.\n                if (n.size() >= 1 && !n.getFirst().isToken()\n                        && n.getFirst().type == NodeType.FN_ARROW_EXPR) {\n                    throw new ParserException(\"invalid \" + siteName + \": arrow function\");\n                }\n                // `this` lexes as IDENT (see JsLexer.keywordOrIdent) but per spec\n                // the ThisExpression has AssignmentTargetType=invalid.\n                if (n.size() >= 1 && n.getFirst().isToken()\n                        && n.getFirst().token.type == IDENT\n                        && \"this\".equals(n.getFirst().getText())) {\n                    throw new ParserException(\"invalid \" + siteName + \": this\");","sourceCodeStart":1688,"sourceCodeEnd":1724,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/parser/JsParser.java#L1688-L1724","documentation":"Karate's parser rejects a destructuring target that was wrapped in parentheses, e.g. `([a, b]) = arr` or `var ({a}) = obj`. Per spec, ObjectLiteral/ArrayLiteral inside parentheses does NOT refine to a destructuring pattern, so the parenthesized form is invalid in binding or assignment position. The message includes the site name for context.","triggerScenarios":"Parsing `([a, b]) = arr;` or `for (const ([x]) of ...)` — after unwrapping PAREN_EXPR, inner is a LIT_EXPR whose first child is LIT_ARRAY or LIT_OBJECT, triggering the error.","commonSituations":"Adding 'protective' parentheses around a destructuring pattern; code adapted from languages where parens are neutral; confusion about the `(a, b) = ...` ambiguity resolution that requires the pattern NOT to be parenthesized.","solutions":["Remove the parentheses around the array/object literal so it refines to a pattern: `[a, b] = arr`","For assignment-position ambiguity cases, keep the pattern bare rather than parenthesized","Rewrite as separate binding/assignment statements if the structure is complex"],"exampleFix":"// before\n([a, b]) = arr; // parenthesized pattern\n// after\n[a, b] = arr;","handlingStrategy":"validation","validationCode":"// flag parenthesized array/object literals in assignment/binding position\nif (/\\(\\s*\\[[^\\]]*\\]\\s*\\)\\s*=[^=]/.test(src) || /\\(\\s*\\{[^}]*\\}\\s*\\)\\s*=[^=]/.test(src)) {\n  throw new Error('parenthesized destructuring pattern is invalid; remove the parentheses');\n}","typeGuard":null,"tryCatchPattern":"try {\n  runScript(src);\n} catch (e) {\n  if (String(e).includes('parenthesized destructuring pattern')) {\n    // remove surrounding parens around the pattern\n  }\n  throw e;\n}","preventionTips":["Never wrap destructuring patterns in parentheses","Know that parens around literals prevent pattern refinement","Add regression tests for each destructuring form used in scripts"],"tags":["javascript","parser","syntax","destructuring"],"backgroundTag":"invalid-argument-format","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"}