karatelabs/karate · error · ParserException
invalid destructuring: rest element cannot have an…
Error message
invalid destructuring: rest element cannot have an initializer
What it means
The Karate JS parser rejects a rest element in array destructuring that carries a default value, e.g. `[...rest = []] = arr`. The spec forbids initializers on rest elements because the rest binding always receives an array (possibly empty) and can never be undefined. Detected statically via restHasInitializer on the last ARRAY_ELEM.
Solutions
- Remove the `= default` from the rest element: `[a, ...rest]`
- Assign the fallback after destructuring: `rest = rest || []` (though rest is always an array)
- If a default is genuinely needed, destructure into a plain binding instead of a rest element
Example fix
// before const [a, ...rest = []] = arr; // after const [a, ...rest] = arr;
Defensive patterns
Strategy: validation
Validate before calling
// flag rest elements with initializers
if (/\.\.\.\s*[A-Za-z_$][\w$]*\s*=/.test(src)) {
throw new Error('script has a rest element with an initializer');
} Try / catch
try {
runScript(src);
} catch (e) {
if (String(e).includes('rest element cannot have an initializer')) {
// strip the = default from the rest element
}
throw e;
} Prevention
- Never write defaults on ...rest elements
- Remember rest is always an array, never undefined
- Lint destructuring patterns before embedding them in scripts
When it happens
Trigger: Parsing patterns like `[a, ...rest = []] = arr;` — hasRestPrefix identifies the rest element and restHasInitializer finds an `=` default after it.
Common situations: Copy-paste where a normal element's default was left on the rest element; defensive coding habits of adding defaults everywhere applied to `...rest` where it is meaningless.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid shorthand initializer: only allowed in…
- invalid destructuring: rest element must be the last…
- invalid
- invalid : parenthesized destructuring pattern
- duplicate binding name
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/761c339445f9b15a.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/parser/JsParser.java:1539
* a spread {@code [...arr, b]} in a regular array literal stays valid.
*/
private static void validateRestElementRules(Node litArray) {
int lastArrayElemIdx = -1;
for (int i = 0, n = litArray.size(); i < n; i++) {
Node ch = litArray.get(i);
if (!ch.isToken() && ch.type == NodeType.ARRAY_ELEM) {
lastArrayElemIdx = i;
}
}
for (int i = 0, n = litArray.size(); i < n; i++) {
Node ch = litArray.get(i);
if (ch.isToken() || ch.type != NodeType.ARRAY_ELEM) continue;
if (!hasRestPrefix(ch)) continue;
if (i != lastArrayElemIdx) {
throw new ParserException("invalid destructuring: rest element must be the last binding element");
}
if (restHasInitializer(ch)) {
throw new ParserException("invalid destructuring: rest element cannot have an initializer");
}
}
}
private static boolean hasRestPrefix(Node arrayElem) {
if (arrayElem.size() == 0) return false;
Node first = arrayElem.getFirst();
return first.isToken() && first.token.type == DOT_DOT_DOT;
}
/**
* For an ARRAY_ELEM that starts with {@code ...}, returns true iff the target
* expression after the DOT_DOT_DOT carries a top-level assignment — i.e. the
* rest target is being given a default value, which is invalid.
*/
private static boolean restHasInitializer(Node arrayElem) {
boolean sawDot = false;
for (int i = 0, n = arrayElem.size(); i < n; i++) {View on GitHub (pinned to a22eb90246)