karatelabs/karate · error · ParserException

invalid : is not a valid assignment target

Error message

invalid ${siteName}: ${nodeType} is not a valid assignment target

What it means

Catch-all rejection in assignment-target validation: when a node of an unhandled type appears in an assignment/binding target position, the parser reports that the node type is not a valid assignment target, naming the concrete NodeType.

Solutions

  1. Make the left side an identifier, property access, or destructuring pattern
  2. Compute the right-hand expression first and assign the result to a variable
  3. Check for swapped operands: often the expression belongs on the right of `=`

Example fix

// before
a + b = total;
// after
const total = a + b;
Defensive patterns

Strategy: validation

Validate before calling

const VALID = ['Identifier','MemberExpression','ObjectPattern','ArrayPattern'];
if (expr.left && !VALID.includes(expr.left.type)) {
  throw new Error('invalid assignment target: ' + expr.left.type);
}

Type guard

function isValidTarget(node) {
  return ['Identifier','MemberExpression','ObjectPattern','ArrayPattern'].includes(node?.type);
}

Try / catch

try {
  karate.eval(code);
} catch (e) {
  if (String(e.message).includes('is not a valid assignment target')) { /* inspect LHS */ }
  throw e;
}

Prevention

When it happens

Trigger: Any syntactic form that is not an identifier, member access, or destructuring pattern placed on the left of `=`, in a destructuring pattern, or in `++`/`--`/compound-assignment positions — e.g. literals (`1 = x`), binary expressions (`a + b = c`), or template literals as targets.

Common situations: Typos like `if x = 1` intent written elsewhere, `a + b = c`, or LHS literals produced by code-generation mistakes.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/10e886357c21c7c9. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/parser/JsParser.java:1746

                // Plain member access; a `?.` would have been caught earlier by
                // the optional-chain branch above with a more specific message.
                // `import.meta` is a meta-property whose AssignmentTargetType is
                // invalid; `import` is not a reserved word in our lexer so it
                // parses as a normal REF_DOT_EXPR — flag the literal shape here.
                if (n.type == NodeType.REF_DOT_EXPR && isImportMeta(n)) {
                    throw new ParserException("invalid " + siteName + ": import.meta");
                }
            }
            case FN_CALL_EXPR -> {
                // Web-compat carve-out (Annex B B.3.5): allow `f() = 1` in non-strict mode.
                // Logical-assignment operators (||=, &&=, ??=) are ES2021 and the carve-out
                // does NOT apply to them; the caller passes noCallCarveOut=true in that case.
                if (noCallCarveOut) {
                    throw new ParserException("invalid " + siteName + ": call expression");
                }
            }
            default ->
                    throw new ParserException("invalid " + siteName + ": "
                            + n.type.name() + " is not a valid assignment target");
        }
    }

    /**
     * Strip thin {@code EXPR} / {@code EXPR_LIST} single-child wrappers introduced
     * by the parser so that callers can inspect the underlying expression shape.
     * Returns the node unchanged once the wrappers run out or the node has more
     * than one child.
     */
    private static Node stripExprWrappers(Node n) {
        while (n != null && n.size() == 1
                && (n.type == NodeType.EXPR || n.type == NodeType.EXPR_LIST)) {
            n = n.get(0);
        }
        return n;
    }

View on GitHub (pinned to a22eb90246)