{"record":{"id":"dd7199367e170a69","repo":"karatelabs/karate","slug":"foreach-needs-two-arguments-collection-and-function","errorCode":null,"errorMessage":"forEach() needs two arguments: collection and function","messagePattern":"forEach\\(\\) needs two arguments: collection and function","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/core/KarateJsUtils.java","lineNumber":241,"sourceCode":"                }\n            } else {\n                // filterKeys(source, key1, key2, ...)\n                for (int i = 1; i < args.length; i++) {\n                    String key = args[i].toString();\n                    if (source.containsKey(key)) {\n                        result.put(key, source.get(key));\n                    }\n                }\n            }\n            return result;\n        };\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    static JavaInvokable forEach() {\n        return args -> {\n            if (args.length < 2) {\n                throw new RuntimeException(\"forEach() needs two arguments: collection and function\");\n            }\n            Object collection = args[0];\n            JavaCallable fn = (JavaCallable) args[1];\n            if (collection instanceof List<?> list) {\n                for (int i = 0; i < list.size(); i++) {\n                    fn.call(null, new Object[]{list.get(i), i});\n                }\n            } else if (collection instanceof Map) {\n                Map<String, Object> map = (Map<String, Object>) collection;\n                int i = 0;\n                for (Map.Entry<String, Object> entry : map.entrySet()) {\n                    fn.call(null, new Object[]{entry.getKey(), entry.getValue(), i++});\n                }\n            }\n            return null;\n        };\n    }\n","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/KarateJsUtils.java#L223-L259","documentation":"Arity guard in the karate.forEach() JS utility: it needs exactly the collection to iterate and the callback function to apply to each element. Fires when forEach() is called with fewer than two arguments; supply both the collection and the function.","triggerScenarios":"Calling forEach(list) without the callback, forEach() empty, or passing something non-callable as the second argument.","commonSituations":"Confusing forEach with Array.prototype.forEach method-call style (list.forEach(fn)) when using the karate.* helper; forgetting the callback during refactors; passing a config object instead of a function.","solutions":["Pass the callback: forEach(list, function(v, i){ ... })","Ensure the first argument is a List or Map","Use the native JS list.forEach(fn) form if iterating plain JS arrays"],"exampleFix":"// before\nkarate.forEach(items);\n// after\nkarate.forEach(items, function(item, i){ karate.log(item, i); });","handlingStrategy":"type-guard","validationCode":"if (!collection || typeof fn !== 'function') throw new Error('forEach requires a collection and a function');","typeGuard":"function canForEach(args) { return args.length >= 2 && args[0] != null && typeof args[1] === 'function'; }","tryCatchPattern":"try { karate.forEach(items, fn); } catch (e) { karate.log('forEach failed: ' + e.message); }","preventionTips":["Pass the callback as the second argument (value, key/index)","Use native array.forEach for plain JS arrays","Initialize collections before iteration"],"tags":["argument-count","callback","javascript","karate"],"backgroundTag":"missing-required-argument","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"}