karatelabs/karate · error · TypeError

RegExp.prototype. called on incompatible receiver

Error message

RegExp.prototype. called on incompatible receiver

What it means

RegExp.prototype.test and RegExp.prototype.exec perform a strict brand check: `this` must be an actual JsRegex instance — no ToString coercion or duck typing. If thisObj is not a JsRegex, a TypeError 'RegExp.prototype.<methodName> called on incompatible receiver' is thrown, per the spec's RequireInternalSlot-style preamble.

Solutions

  1. Call the method bound to a real regex: re.test(str) or re.test.bind(re) when passing as a callback
  2. Ensure the receiver is an actual RegExp instance, not a string or plain object
  3. For one-off checks on strings, use the free forms str.match(re), str.search(re), or re.test(...)/re.exec(...) on a constructed RegExp

Example fix

// before
['a1','b2'].map(re.test); // this lost -> TypeError
// after
['a1','b2'].map(s => re.test(s)); // or re.test.bind(re)
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(re instanceof RegExp)) throw new Error('test/exec receiver must be a RegExp, got: ' + typeof re);
return re.test(str);

Type guard

const isRegex = v => v instanceof RegExp;
const matches = (v, s) => isRegex(v) ? v.test(s) : new RegExp(String(v)).test(s);

Try / catch

try {
  return re.test(input);
} catch (e) {
  if (String(e.message).includes('incompatible receiver')) {
    throw new Error('test/exec called with lost `this`; bind the regex');
  }
  throw e;
}

Prevention

When it happens

Trigger: const t = re.test; t('str') (this becomes undefined); RegExp.prototype.test.call({}, 'x'); calling test/exec on a plain object or a string (e.g. 'abc'.test(...) style mistakes); applying the methods to regex-like data from another source.

Common situations: Extracting test/exec as callbacks (arr.map(re.test)) which loses `this`; typos like someString.exec(pattern); passing mock/duck-typed regex objects in tests; migrating code from libraries whose regex methods coerced `this`.

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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsRegexPrototype.java:90

    // via {@code userProps}).
    private void installFlagAccessor(String name, Object protoSentinel,
                                      Function<JsRegex, Object> extractor) {
        JsCallable lambda = (ctx, args) -> {
            Object thisObj = ctx.getThisObject();
            if (thisObj == this) return protoSentinel;
            if (thisObj instanceof JsRegex r) return extractor.apply(r);
            throw JsErrorException.typeError("get RegExp.prototype." + name + " called on incompatible receiver");
        };
        JsBuiltinMethod getter = new JsBuiltinMethod("get " + name, 0, lambda);
        installAccessor(name, getter, null, ACCESSOR_ATTRS);
    }

    // Spec preamble for test / exec — RegExp objects are required (no ToString
    // coercion of `this`); the search string is ToString-coerced.
    private static JsRegex requireRegex(Context context, String methodName) {
        Object thisObj = context.getThisObject();
        if (thisObj instanceof JsRegex r) return r;
        throw JsErrorException.typeError("RegExp.prototype." + methodName + " called on incompatible receiver");
    }

    private static String argString(Object[] args, Context context) {
        Object arg = args.length > 0 ? args[0] : Terms.UNDEFINED;
        if (arg instanceof String s) return s;
        if (arg instanceof JsString js) return js.text;
        return Terms.toStringCoerce(arg, context instanceof CoreContext cc ? cc : null);
    }

    // Instance methods

    private Object test(Context context, Object[] args) {
        return requireRegex(context, "test").test(argString(args, context));
    }

    private Object exec(Context context, Object[] args) {
        return requireRegex(context, "exec").exec(argString(args, context));
    }

View on GitHub (pinned to a22eb90246)