karatelabs/karate · error · TypeError
Method Set.prototype called on incompatible receiver
Error message
Method Set.prototype called on incompatible receiver
What it means
A Set.prototype method (add, has, delete, clear, etc.) was invoked with a `this` that is not an actual Set instance. The engine resolves the receiver with asSet() and throws a TypeError when it is anything else.
Solutions
- Call the method on a real Set instance created with new Set().
- Use .call/.apply only with a genuine Set as the first argument.
- Bind the method once and reuse the bound instance: const has = mySet.has.bind(mySet).
- Validate with instanceof Set before invoking its methods.
Example fix
// before const has = mySet.has; has(value); // after const has = mySet.has.bind(mySet); has(value);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(s instanceof Set)) throw new TypeError('expected a Set'); Type guard
function isSet(v) { return v instanceof Set; } Try / catch
try { return mySet.has(value); } catch (e) { if (String(e).includes('incompatible receiver')) { const s = new Set(); return false; } throw e; } Prevention
- Bind extracted methods immediately: const has = mySet.has.bind(mySet).
- Use instanceof Set checks before calling Set.prototype methods via call/apply.
- Avoid optional-chaining on values you have not confirmed are Sets.
When it happens
Trigger: Extracting a method and calling it unbound: const h = new Set().has; h(...); or Set.prototype.add.call(nonSet, v); or calling .has on undefined/null due to a chained lookup that silently returned undefined.
Common situations: Method borrowing from prototypes; passing a plain object or Map where a Set was expected; optional-chaining chains that skipped construction (e.g. maybeSet?.has(x) where maybeSet is not a Set).
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- BigInt.prototype method called on non-BigInt
- Constructor Set requires 'new'
- Error.prototype.toString called on non-object
- Method Promise.prototype called on incompatible receiver
- Method WeakMap.prototype called on incompatible receiver
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/ec518659b1c74598.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsSetPrototype.java:73
// to integer, validate callability). Result-bearing methods build a
// fresh JsSet by populating elements directly (spec bypasses
// Set.prototype.add — verified by add-not-called.js test262).
install("union", 1, this::union);
install("intersection", 1, this::intersection);
install("difference", 1, this::difference);
install("symmetricDifference", 1, this::symmetricDifference);
install("isSubsetOf", 1, this::isSubsetOf);
install("isSupersetOf", 1, this::isSupersetOf);
install("isDisjointFrom", 1, this::isDisjointFrom);
installConstructor("Set");
}
private static JsSet asSet(Context context) {
Object thisObj = context.getThisObject();
if (thisObj instanceof JsSet s) {
return s;
}
throw JsErrorException.typeError("Method Set.prototype called on incompatible receiver");
}
private Object add(Context context, Object[] args) {
JsSet s = asSet(context);
s.addValue(args.length > 0 ? args[0] : Terms.UNDEFINED);
return s;
}
private Object has(Context context, Object[] args) {
return asSet(context).has(args.length > 0 ? args[0] : Terms.UNDEFINED);
}
private Object delete(Context context, Object[] args) {
return asSet(context).deleteValue(args.length > 0 ? args[0] : Terms.UNDEFINED);
}
private Object clear(Context context, Object[] args) {
asSet(context).clearAll();View on GitHub (pinned to a22eb90246)