karatelabs/karate · error · JsErrorException
Reduce of empty array with no initial value
Error message
Reduce of empty array with no initial value
What it means
Array.prototype.reduce without an initial value on an array with no elements has no seed for the accumulator, so the spec mandates a TypeError. Karate throws 'Reduce of empty array with no initial value' in its reduce implementation when the callback never ran (hasAcc still false).
Solutions
- Provide an initial value: arr.reduce(fn, 0) (or [], {}, as appropriate)
- Check the array is non-empty before reducing: if (arr.length === 0) return default;
- Handle empty data at the source (server returned an empty list)
- Catch the TypeError and return a default
Example fix
// before const total = items.reduce((a, b) => a + b.price,); // after const total = items.reduce((a, b) => a + b.price, 0);
Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(items) || items.length === 0) return 0; // default seed
Type guard
function isNonEmptyArray(a) { return Array.isArray(a) && a.length > 0; } Try / catch
try { return items.reduce(fn); } catch (e) { if (String(e.message).includes('Reduce of empty array')) return 0; throw e; } Prevention
- Always supply an initialValue to reduce
- Check array emptiness after filtering before folding
- Treat empty API responses as a first-class case in scripts
When it happens
Trigger: [].reduce(fn) or arr.reduce(fn) where arr is empty and no second (initialValue) argument is supplied.
Common situations: Summing/merging over data that turned out empty (empty JSON array from an API or empty karate response); filtering before reducing removed all elements; reduce used where reduceRight/initial value was intended.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Array.from requires an iterable or array-like object, not
- is not iterable
- Cannot assign to read only property 'length' of object…
- Array.prototype.* called on null or undefined
- callback is not a function
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/a550207c47cd82fc.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsArrayPrototype.java:893
// is acceptable churn against the much larger
// {@code (function(){return this.x}).reduce(...)} body of in-the-wild
// code that depends on natural {@code this} propagation.
JsCallable callable = requireCallable(args, "Array.prototype.reduce");
Object thisObj = context.getThisObject();
Object[] acc = new Object[1];
boolean[] hasAcc = {args.length >= 2};
if (hasAcc[0]) acc[0] = args[1];
specIterate(context, true, true, (k, v) -> {
if (!hasAcc[0]) {
acc[0] = v;
hasAcc[0] = true;
return true;
}
acc[0] = callable.call(context, new Object[]{acc[0], v, k, thisObj});
return true;
});
if (!hasAcc[0]) {
throw JsErrorException.typeError("Reduce of empty array with no initial value");
}
return acc[0];
}
private Object reduceRight(Context context, Object[] args) {
JsCallable callable = requireCallable(args, "Array.prototype.reduceRight");
Object thisObj = context.getThisObject();
Object[] acc = new Object[1];
boolean[] hasAcc = {args.length >= 2};
if (hasAcc[0]) acc[0] = args[1];
specIterate(context, false, true, (k, v) -> {
if (!hasAcc[0]) {
acc[0] = v;
hasAcc[0] = true;
return true;
}
acc[0] = callable.call(context, new Object[]{acc[0], v, k, thisObj});
return true;View on GitHub (pinned to a22eb90246)