{"record":{"id":"9dd8b1c48bd75557","repo":"karatelabs/karate","slug":"method-map-prototype-called-on-incompatible-receiver","errorCode":null,"errorMessage":"Method Map.prototype called on incompatible receiver","messagePattern":"Method Map\\.prototype called on incompatible receiver","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsMapPrototype.java","lineNumber":68,"sourceCode":"        install(\"keys\", 0, this::keys);\n        install(\"values\", 0, this::values);\n        JsBuiltinMethod entries = new JsBuiltinMethod(\"entries\", 0, this::entriesMethod);\n        install(\"entries\", entries);\n        // Spec @@iterator on Map.prototype === Map.prototype.entries — same\n        // wrapped instance keeps identity.\n        install(IterUtils.SYMBOL_ITERATOR, entries);\n        // ES2025 upsert proposal — Map.prototype.{getOrInsert, getOrInsertComputed}.\n        install(\"getOrInsert\", 2, this::getOrInsert);\n        install(\"getOrInsertComputed\", 2, this::getOrInsertComputed);\n        installConstructor(\"Map\");\n    }\n\n    private static JsMap asMap(Context context) {\n        Object thisObj = context.getThisObject();\n        if (thisObj instanceof JsMap m) {\n            return m;\n        }\n        throw JsErrorException.typeError(\"Method Map.prototype called on incompatible receiver\");\n    }\n\n    private Object get(Context context, Object[] args) {\n        return asMap(context).getValue(args.length > 0 ? args[0] : Terms.UNDEFINED);\n    }\n\n    private Object set(Context context, Object[] args) {\n        JsMap m = asMap(context);\n        Object key = args.length > 0 ? args[0] : Terms.UNDEFINED;\n        Object value = args.length > 1 ? args[1] : Terms.UNDEFINED;\n        m.setValue(key, value);\n        return m;\n    }\n\n    private Object has(Context context, Object[] args) {\n        return asMap(context).hasKey(args.length > 0 ? args[0] : Terms.UNDEFINED);\n    }\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsMapPrototype.java#L50-L86","documentation":"Map.prototype methods (get, set, has, delete, clear, etc.) must be invoked on an actual Map instance as `this`. Karate's `asMap` checks `context.getThisObject() instanceof JsMap` and throws this TypeError otherwise, mirroring the ES spec's MakeOrdinaryObjectCheck on the receiver.","triggerScenarios":"Calling the method detached from the instance: `const g = map.get; g('key')`; destructuring methods off a Map; `Map.prototype.get.call(nonMapObject, 'k')`; calling a prototype method after the instance was replaced with a plain object.","commonSituations":"Extracting methods into callbacks (e.g. `arr.map(map.get)`) without binding; applying Map methods via .call/.apply to plain objects; refactors that lost the receiver.","solutions":["Bind the method: `const get = map.get.bind(map)`","Use arrow wrappers: `arr.map(k => map.get(k))`","Ensure .call/.apply receivers are real `new Map()` instances","Recreate the Map if the value was accidentally replaced by a plain object"],"exampleFix":"// before\nconst get = map.get;\nconst v = get('key'); // TypeError\n// after\nconst get = map.get.bind(map);\nconst v = get('key');","handlingStrategy":"type-guard","validationCode":"if (!(m instanceof Map)) { throw new Error('receiver must be a real Map instance'); }","typeGuard":"function isMap(x) { return x instanceof Map; }","tryCatchPattern":"try {\n  return mapLike.get('key');\n} catch (e) {\n  if (String(e.message).includes('incompatible receiver')) {\n    throw new Error('called a Map.prototype method without a Map as this — bind the method');\n  } else throw e;\n}","preventionTips":["Never destructure Map methods without .bind(map)","Use arrow-function wrappers for callbacks: (k) => map.get(k)","Check .call/.apply receivers are Map instances"],"tags":["javascript","map","receiver","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"}