karatelabs/karate · error · JsErrorException
Map.prototype.set is not callable
Error message
Map.prototype.set is not callable
What it means
Karate's JS engine throws this while constructing a Map from an iterable, per spec 24.1.1.1 step 9: it looks up `set` on the new map's prototype chain and requires it to be a callable function. If `Map.prototype.set` was deleted, overwritten with a non-function, or the map instance's prototype was mangled, construction aborts with this TypeError.
Solutions
- Restore the built-in: remove any `Map.prototype.set = ...` override or delete it before constructing Maps
- Ensure any Map polyfill/shim defines `set` as a function
- Check that code does not reassign an object's prototype (`Object.setPrototypeOf`) away from Map.prototype before passing it through `new Map()`
- Isolate the mutating script — run the Map construction in a fresh Karate JS context
Example fix
// before Map.prototype.set = null; const m = new Map([[1, 'a']]); // TypeError // after Map.prototype.set = origSet; // restore or don't override const m = new Map([[1, 'a']]);
Defensive patterns
Strategy: type-guard
Validate before calling
// before constructing
if (typeof Map.prototype.set !== 'function') {
throw new Error('Map.prototype.set was clobbered; restore it before new Map(iterable)');
} Type guard
function mapSetIsCallable() { return typeof Map.prototype.set === 'function'; } Try / catch
try {
const m = new Map(iterable);
} catch (e) {
if (String(e.message).includes('Map.prototype.set is not callable')) {
// restore built-in / run in clean context
} else throw e;
} Prevention
- Don't monkey-patch Map.prototype in test setup
- Snapshot built-ins and restore in teardown
- Run untrusted scripts in isolated contexts
When it happens
Trigger: Passing an iterable to `new Map(iterable)` after user code has done `Map.prototype.set = null` / `delete Map.prototype.set`, or reassigned a Map instance's prototype to a plain object lacking a callable `set`.
Common situations: Monkey-patching Map.prototype in test setup or polyfills that accidentally clobber built-ins; transpilers or DSL code overriding Map methods; running JS that mutates global built-ins before constructing Maps.
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
- Constructor Map requires 'new'
- Iterator value is not an entry object
- Method Map.prototype called on incompatible receiver
- Map.prototype.forEach: callback is not a function
- WeakMap.prototype.set is not callable
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/00810a7028f3791e.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsMapConstructor.java:72
GroupByImpl.run(items, callback, /* propertyMode= */ false, context));
}
@Override
public Object call(Context context, Object[] args) {
CallInfo callInfo = context.getCallInfo();
boolean isNew = callInfo != null && callInfo.constructor;
if (!isNew) {
throw JsErrorException.typeError("Constructor Map requires 'new'");
}
JsMap map = new JsMap();
if (args.length == 0 || args[0] == null || args[0] == Terms.UNDEFINED) {
return map;
}
// Look up `set` on the freshly-constructed map's prototype chain — honors
// user-overridden Map.prototype.set per spec 24.1.1.1 step 9.
Object setFn = map.getMember("set");
if (!(setFn instanceof JsCallable adder)) {
throw JsErrorException.typeError("Map.prototype.set is not callable");
}
JsIterator iter = IterUtils.getIterator(args[0], context);
CoreContext cc = context instanceof CoreContext c ? c : null;
Object savedThis = cc != null ? cc.thisObject : null;
try {
while (iter.hasNext()) {
Object entry = iter.next();
if (!(entry instanceof List) && !(entry instanceof ObjectLike)) {
throw JsErrorException.typeError("Iterator value " + entry + " is not an entry object");
}
Object k;
Object v;
if (entry instanceof List<?> list) {
k = list.isEmpty() ? Terms.UNDEFINED : list.get(0);
v = list.size() < 2 ? Terms.UNDEFINED : list.get(1);
} else {
ObjectLike ol = (ObjectLike) entry;
k = ol.getMember("0");View on GitHub (pinned to a22eb90246)