{"record":{"id":"b1757a957c259938","repo":"karatelabs/karate","slug":"invalid-value-used-as-weak-map-key","errorCode":null,"errorMessage":"Invalid value used as weak map key","messagePattern":"Invalid value used as weak map key","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsWeakMap.java","lineNumber":67,"sourceCode":"    /** Spec CanBeHeldWeakly: objects only. Real WeakMaps also accept\n     *  non-registered symbols, but this engine has no symbol primitive. */\n    static boolean canBeHeldWeakly(Object value) {\n        return !Terms.isPrimitive(value);\n    }\n\n    boolean hasKey(Object key) {\n        return canBeHeldWeakly(key) && entries.containsKey(key);\n    }\n\n    Object getValue(Object key) {\n        // containsKey, not get() == null — a stored JS null is a Java null value\n        // and must not read back as undefined.\n        return hasKey(key) ? entries.get(key) : Terms.UNDEFINED;\n    }\n\n    void setValue(Object key, Object value) {\n        if (!canBeHeldWeakly(key)) {\n            throw JsErrorException.typeError(\"Invalid value used as weak map key\");\n        }\n        entries.put(key, value);\n    }\n\n    boolean deleteKey(Object key) {\n        if (!hasKey(key)) {\n            return false;\n        }\n        entries.remove(key);\n        return true;\n    }\n\n}\n","sourceCodeStart":49,"sourceCodeEnd":81,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsWeakMap.java#L49-L81","documentation":"JavaScript's WeakMap can only hold keys that the garbage collector can track: objects, or symbols registered in a global symbol registry (per spec, non-registered symbols are also rejected). Karate's JsWeakMap enforces this via canBeHeldWeakly(key) and throws a TypeError when set() is given a primitive like a number, string, or undefined. This matches V8's own 'Invalid value used as weak map key' TypeError.","triggerScenarios":"Calling weakMap.set(key, value) where key is a primitive (number, string, boolean, null, undefined, bigint, or an unregistered symbol), e.g. new WeakMap().set(42, 'x') or new WeakMap().set('id', obj).","commonSituations":"Migrating code from Map to WeakMap where keys were string IDs; JSON-deserialized data where keys came back as strings instead of object references; accidental use of undefined because the key variable was never assigned.","solutions":["Use an object (or a registered symbol via Symbol.for) as the key: weakMap.set(keyObj, value).","If you need primitive keys, use a regular Map instead of WeakMap.","Guard the key before calling set: only pass values where typeof k === 'object' ? k !== null : typeof k === 'function' (or registered symbols).","Check for null/undefined key variables upstream — often a failed lookup returned undefined."],"exampleFix":"// before\nconst cache = new WeakMap();\ncache.set(userId, profile); // TypeError: primitive key\n\n// after\nconst cache = new Map();          // primitives allowed\ncache.set(userId, profile);","handlingStrategy":"validation","validationCode":"function isWeakKey(k) { return (typeof k === 'object' && k !== null) || typeof k === 'function' || (typeof k === 'symbol' && k === Symbol.for(String(k))); }\nif (!isWeakKey(key)) throw new Error('weak map key must be an object');\nwm.set(key, value);","typeGuard":"function isWeakKey(k) { return (typeof k === 'object' && k !== null) || typeof k === 'function'; }","tryCatchPattern":null,"preventionTips":["Use Map for primitive keys, WeakMap only for object-keyed metadata","Never pass JSON-derived values as WeakMap keys without checking type","Validate key variables are defined before set()"],"tags":["javascript","weakmap","typeerror"],"backgroundTag":"invalid-argument-value","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"}