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
- Call the method bound to a real regex: re.test(str) or re.test.bind(re) when passing as a callback
- Ensure the receiver is an actual RegExp instance, not a string or plain object
- 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
- Never detach test/exec from their regex (avoid arr.map(re.test)); use an arrow wrapper or .bind(re)
- Do not call test/exec on strings or plain objects; use str.match/str.search instead
- Ensure mocks and regex-like values from other libraries are real RegExp instances
- Type-check regex receivers in helpers that accept 'anything regex-shaped'
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
- RegExp.escape called on non-string
- get RegExp.prototype. called on incompatible receiver
- Method WeakMap.prototype called on incompatible receiver
- Method WeakSet.prototype called on incompatible receiver
- Cannot set property ' ' which has only a getter
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)