karatelabs/karate · error · ParserException

invalid : this

Error message

invalid ${siteName}: this

What it means

Per the ECMAScript spec, the `this` keyword is a ThisExpression whose AssignmentTargetType is invalid, so it cannot appear on the left-hand side of an assignment or in a binding position. The lexer emits `this` as IDENT, but the parser explicitly flags it here when validating assignment targets.

Solutions

  1. Assign to a normal variable instead of `this`
  2. Use `const self = this;` if you need an alias for the current context
  3. Use an arrow function to lexically capture `this` rather than rebinding it

Example fix

// before
this = {};
// after
const self = this;
// mutate properties instead: this.foo = 1;
Defensive patterns

Strategy: validation

Validate before calling

if (/\bthis\s*=[^=]/.test(code)) {
  throw new Error('`this` cannot be assigned');
}

Type guard

function assignsThis(node) {
  return node.type === 'AssignmentExpression' &&
    node.left.type === 'ThisExpression';
}

Try / catch

try {
  karate.eval(code);
} catch (e) {
  if (String(e.message).includes(': this')) { /* rewrite to variable */ }
  throw e;
}

Prevention

When it happens

Trigger: Code like `this = obj`, `[this] = arr`, or `({a: this} = o)` where `this` occupies an assignment/destructuring target position.

Common situations: Mistakenly trying to rebind `this` (a habit from other languages such as Python where `self` is assignable); typo writing `this =` instead of `self = this`-style patterns.

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/badd33188ab26492. Report an issue: GitHub.

Appendix: source

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

                    throw new ParserException("invalid " + siteName + ": parenthesized destructuring pattern");
                }
            }
            n = inner;
        }
        switch (n.type) {
            case REF_EXPR -> {
                // REF_EXPR is single-arg arrow `x => ...` when its first child is an
                // FN_ARROW_EXPR rather than the IDENT token; that form is invalid.
                if (n.size() >= 1 && !n.getFirst().isToken()
                        && n.getFirst().type == NodeType.FN_ARROW_EXPR) {
                    throw new ParserException("invalid " + siteName + ": arrow function");
                }
                // `this` lexes as IDENT (see JsLexer.keywordOrIdent) but per spec
                // the ThisExpression has AssignmentTargetType=invalid.
                if (n.size() >= 1 && n.getFirst().isToken()
                        && n.getFirst().token.type == IDENT
                        && "this".equals(n.getFirst().getText())) {
                    throw new ParserException("invalid " + siteName + ": this");
                }
            }
            case REF_DOT_EXPR, REF_BRACKET_EXPR -> {
                // 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");

View on GitHub (pinned to a22eb90246)