{"record":{"id":"5e9cc16303beb57e","repo":"karatelabs/karate","slug":"groupby-called-with-null-or-undefined-items","errorCode":null,"errorMessage":"groupBy called with null or undefined items","messagePattern":"groupBy called with null or undefined items","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/GroupByImpl.java","lineNumber":65,"sourceCode":"        final List<Object> values = new ArrayList<>();\n\n        Group(Object key) {\n            this.key = key;\n        }\n    }\n\n    /**\n     * Walks {@code items} via the spec iterator protocol, invokes\n     * {@code callback(value, k)} for each element, coerces the return value\n     * into a key per {@code propertyMode} (true → ToPropertyKey, false →\n     * -0 → +0 normalize), and accumulates values into groups in\n     * first-seen-key order. Group key equality uses {@link Terms#sameValue}\n     * (matches spec for the Map.groupBy case; for property-mode the keys are\n     * always strings and SameValue collapses to equals).\n     */\n    static List<Group> run(Object items, Object callback, boolean propertyMode, Context context) {\n        if (items == null || items == Terms.UNDEFINED) {\n            throw JsErrorException.typeError(\"groupBy called with null or undefined items\");\n        }\n        if (!(callback instanceof JsCallable cb)) {\n            throw JsErrorException.typeError(\"groupBy callback is not a function\");\n        }\n        CoreContext cc = context instanceof CoreContext c ? c : null;\n        JsIterator iter = IterUtils.getIterator(items, context);\n        List<Group> groups = new ArrayList<>();\n        long k = 0;\n        while (iter.hasNext()) {\n            Object value = iter.next();\n            Object rawKey = cb.call(context, new Object[]{value, (double) k});\n            // IfAbruptCloseIterator: a callback that threw via context.error\n            // ends iteration without re-grouping. Surface the same error to\n            // our caller (already on cc.error).\n            if (cc != null && cc.isError()) {\n                return groups;\n            }\n            Object key;","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/GroupByImpl.java#L47-L83","documentation":"GroupByImpl.run throws this TypeError when the items argument to groupBy (Object.groupBy / Map.groupBy style API, also property-mode) is null or undefined. There is nothing to iterate, so instead of a confusing downstream iterator failure the engine fails fast with an explicit message.","triggerScenarios":"Calling the groupBy helper with a variable that is null/undefined — e.g. an unset karate variable, a function that returned undefined, or a missing response field passed as the collection.","commonSituations":"Chained operations where an earlier step returned nothing (`response.foo` when foo is absent); optional JSON paths that yielded null; config values not yet set before the groupBy call.","solutions":["Ensure the items argument is an array or iterable before calling groupBy (default it to [])","Null-check the source expression (karate: `karate.isNull(x)`, JS: `x ?? []`)","Fix the upstream step that produced null/undefined (missing response field, wrong path)","If null is meaningful, branch around the groupBy call instead of passing null"],"exampleFix":"// before\nconst groups = groupBy(response.items, x => x.type);\n// after\nconst groups = groupBy(response.items ?? [], x => x.type);","handlingStrategy":"validation","validationCode":"if (items == null) throw new Error('groupBy: items required');\n// or in JS: if (items == null) items = [];","typeGuard":"function isIterableItems(x) { return x != null && typeof x[Symbol.iterator] === 'function'; }","tryCatchPattern":"try { groupBy(items, cb); } catch (e) { if (String(e).includes('null or undefined')) { items = []; } else { throw e; } }","preventionTips":["Default optional inputs with ?? or || []","Validate API response fields before grouping","Fix upstream producers that return undefined"],"tags":["javascript","groupby","typeerror","null","undefined"],"backgroundTag":"null-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"}