{"record":{"id":"7a54c6587d807451","repo":"karatelabs/karate","slug":"method-weakmap-prototype-called-on-incompatible-receiver","errorCode":null,"errorMessage":"Method WeakMap.prototype called on incompatible receiver","messagePattern":"Method WeakMap\\.prototype called on incompatible receiver","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsWeakMapPrototype.java","lineNumber":51,"sourceCode":"    static final JsWeakMapPrototype INSTANCE = new JsWeakMapPrototype();\n\n    private JsWeakMapPrototype() {\n        super(JsObjectPrototype.INSTANCE);\n        install(\"get\", 1, this::get);\n        install(\"set\", 2, this::set);\n        install(\"has\", 1, this::has);\n        install(\"delete\", 1, this::delete);\n        // Spec tags WeakMap via @@toStringTag rather than a builtin class check.\n        install(\"@@toStringTag\", \"WeakMap\");\n        installConstructor(\"WeakMap\");\n    }\n\n    private static JsWeakMap asWeakMap(Context context) {\n        Object thisObj = context.getThisObject();\n        if (thisObj instanceof JsWeakMap m) {\n            return m;\n        }\n        throw JsErrorException.typeError(\"Method WeakMap.prototype called on incompatible receiver\");\n    }\n\n    private Object get(Context context, Object[] args) {\n        return asWeakMap(context).getValue(args.length > 0 ? args[0] : Terms.UNDEFINED);\n    }\n\n    private Object set(Context context, Object[] args) {\n        JsWeakMap m = asWeakMap(context);\n        m.setValue(args.length > 0 ? args[0] : Terms.UNDEFINED, args.length > 1 ? args[1] : Terms.UNDEFINED);\n        return m;\n    }\n\n    private Object has(Context context, Object[] args) {\n        return asWeakMap(context).hasKey(args.length > 0 ? args[0] : Terms.UNDEFINED);\n    }\n\n    private Object delete(Context context, Object[] args) {\n        return asWeakMap(context).deleteKey(args.length > 0 ? args[0] : Terms.UNDEFINED);","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsWeakMapPrototype.java#L33-L69","documentation":"WeakMap prototype methods (get, set, has, delete) must be invoked with a real JsWeakMap as `this`. Karate's asWeakMap() inspects context.getThisObject() and throws this TypeError when the receiver is not a JsWeakMap — for example when a method is detached and called standalone, or called on a subclass/proxy instance that isn't the engine's WeakMap class.","triggerScenarios":"const g = wm.get; g(key) (unbound method); WeakMap.prototype.has.call(nonWeakMap, key); calling methods on an object that merely looks like a WeakMap; calling a prototype method via call/apply with the wrong this.","commonSituations":"Extracting methods for callbacks (forEach-style usage) without binding; mixing WeakMaps across script contexts/engines where classes differ; passing map-like mocks into helper functions.","solutions":["Bind methods before detaching: const g = wm.get.bind(wm).","Always call methods on the instance: wm.get(key), not WeakMap.prototype.get.call(other, key).","Ensure helper functions receive the actual WeakMap instance created in the same engine.","If you need generic behavior, accept the map as a parameter and call methods on it directly."],"exampleFix":"// before\nconst get = wm.get;\nget(key); // incompatible receiver\n\n// after\nconst get = wm.get.bind(wm);\nget(key);","handlingStrategy":"type-guard","validationCode":"if (!(m instanceof WeakMap)) throw new Error('receiver must be a WeakMap');","typeGuard":"function isWeakMap(x) { try { WeakMap.prototype.set.call(x, {}, 1); return true; } catch (e) { return false; } }","tryCatchPattern":"try { return wm.get(key); } catch (e) { if (String(e).indexOf('incompatible receiver') !== -1) throw new Error('use wm.get.bind(wm) before detaching methods'); throw e; }","preventionTips":["Bind methods before extracting them from instances","Call prototype methods only with genuine WeakMap receivers","Create and use WeakMaps within the same script/engine context"],"tags":["javascript","weakmap","this-binding","typeerror"],"backgroundTag":"type-mismatch","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}