{"record":{"id":"12ddf34dfb096303","repo":"karatelabs/karate","slug":"set-prototype-foreach-callback-is-not-a-function","errorCode":null,"errorMessage":"Set.prototype.forEach: callback is not a function","messagePattern":"Set\\.prototype\\.forEach: callback is not a function","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsSetPrototype.java","lineNumber":98,"sourceCode":"    }\n\n    private Object has(Context context, Object[] args) {\n        return asSet(context).has(args.length > 0 ? args[0] : Terms.UNDEFINED);\n    }\n\n    private Object delete(Context context, Object[] args) {\n        return asSet(context).deleteValue(args.length > 0 ? args[0] : Terms.UNDEFINED);\n    }\n\n    private Object clear(Context context, Object[] args) {\n        asSet(context).clearAll();\n        return Terms.UNDEFINED;\n    }\n\n    private Object forEach(Context context, Object[] args) {\n        JsSet s = asSet(context);\n        if (args.length == 0 || !(args[0] instanceof JsCallable cb)) {\n            throw JsErrorException.typeError(\"Set.prototype.forEach: callback is not a function\");\n        }\n        Object thisArg = args.length > 1 ? args[1] : Terms.UNDEFINED;\n        CoreContext cc = context instanceof CoreContext c ? c : null;\n        Object savedThis = cc != null ? cc.thisObject : null;\n        try {\n            // Spec: forEach walks the live entry list. Entries added after the cursor\n            // (at the end) are visited; entries deleted before the cursor reaches them\n            // are skipped. Re-fetch the keyset on each step so additions show up.\n            int cursor = 0;\n            while (cursor < s.elements.size()) {\n                Iterator<Object> it = s.elements.keySet().iterator();\n                for (int i = 0; i < cursor && it.hasNext(); i++) it.next();\n                if (!it.hasNext()) break;\n                Object v = it.next();\n                if (cc != null) cc.thisObject = thisArg;\n                // Per spec: callback receives (value, value, set) — both first args identical\n                // (sets have no separate key vs value).\n                cb.call(context, new Object[]{v, v, s});","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsSetPrototype.java#L80-L116","documentation":"Set.prototype.forEach requires its first argument to be a callable callback function; a non-function (including undefined) was supplied. This mirrors the spec TypeError for non-function iterables' callbacks.","triggerScenarios":"mySet.forEach() with no args; mySet.forEach('notAFunction'); passing a value that is null/undefined because a callback variable was never initialized.","commonSituations":"Typos where the intended callback name is misspelled or out of scope; optional callbacks defaulted to undefined instead of a no-op; refactors that dropped the arrow function.","solutions":["Pass a function: mySet.forEach(v => console.log(v)).","Default optional callbacks: cb = cb || (() => {}).","Validate typeof callback === 'function' before calling forEach."],"exampleFix":"// before\nmySet.forEach(callbackName);\n// after\nif (typeof callbackName === 'function') { mySet.forEach(callbackName); }","handlingStrategy":"validation","validationCode":"if (typeof cb !== 'function') cb = () => {};","typeGuard":"function isFn(v) { return typeof v === 'function'; }","tryCatchPattern":"try { mySet.forEach(cb); } catch (e) { if (String(e).includes('callback is not a function')) mySet.forEach(v => process(v)); else throw e; }","preventionTips":["Always pass an explicit function to forEach.","Default optional callbacks to a no-op function, not undefined.","Check for misspelled callback identifiers."],"tags":["javascript","set","callback"],"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-19T12:17:13.211Z"}