karatelabs/karate · error · JsErrorException
AggregateError requires an iterable of errors
Error message
AggregateError requires an iterable of errors
What it means
AggregateError's first argument must be iterable (spec §20.5.7.1.1 step 3); its elements become the `errors` property. Passing null or undefined means there is nothing to iterate, so Karate throws this TypeError before iteration begins.
Solutions
- Pass an array (even empty): new AggregateError([], 'message').
- Default the argument: new AggregateError(errors ?? [], msg).
- Fix upstream code that produces null instead of an errors array.
Example fix
// before throw new AggregateError(errors, 'all failed'); // TypeError when errors is null // after throw new AggregateError(errors ?? [], 'all failed');
Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(errors)) throw new Error('AggregateError needs an array of errors'); Type guard
function isIterable(v) { return v != null && typeof v[Symbol.iterator] === 'function'; } Try / catch
try { throw new AggregateError(errors ?? [], 'aggregated'); } catch (e) { if (e instanceof TypeError && /iterable of errors/.test(e.message)) { /* fix args */ } throw e; } Prevention
- Default the first constructor argument to [] with ?? or ||.
- Initialize error-collector arrays before conditional loops fill them.
- When wrapping Promise.any rejections, pass e.errors (always an array).
When it happens
Trigger: new AggregateError(), new AggregateError(null), new AggregateError(undefined), or a variable holding null passed as the errors argument (e.g. collected errors list that was never initialized).
Common situations: Promise.any-style aggregation code where the error list is conditionally built, refactoring that changed an empty array to null, unhandled Promise.any rejection handlers forwarding null.
Related errors
- Array.from requires an iterable or array-like object, not
- is not iterable
- Array.prototype.* called on null or undefined
- BigInt.prototype method called on non-BigInt
- BigInts have no unsigned right shift, use >> instead
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/68cf094422fadfa4.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsErrorConstructor.java:97
*/
private static String toMessageString(Object value, CoreContext cc) {
if (value instanceof ObjectLike inner && cc != null) {
value = Terms.toPrimitive(inner, "string", cc);
if (cc.isError()) return null;
}
if (value == null) return "null";
if (value == Terms.UNDEFINED) return "undefined";
return value.toString();
}
/**
* AggregateError(errors, message?, options?): iterate errors into an Array
* own property, set message + cause as for plain Error. Spec §20.5.7.1.1.
*/
private Object constructAggregate(Context context, Object[] args) {
Object errorsArg = args.length > 0 ? args[0] : Terms.UNDEFINED;
if (errorsArg == null || errorsArg == Terms.UNDEFINED) {
throw JsErrorException.typeError("AggregateError requires an iterable of errors");
}
CoreContext cc = context instanceof CoreContext c ? c : null;
List<Object> collected = new ArrayList<>();
JsIterator iter = IterUtils.getIterator(errorsArg, context);
while (iter.hasNext()) {
collected.add(iter.next());
}
String message = null;
if (args.length > 1 && args[1] != Terms.UNDEFINED) {
message = toMessageString(args[1], cc);
if (cc != null && cc.isError()) return Terms.UNDEFINED;
}
JsError instance = new JsError(errorPrototype);
if (message != null) {
instance.defineOwn("message", message, MESSAGE_ATTRS);
}
instance.captureStack(cc);
installCauseFromOptions(instance, args, 2, cc);View on GitHub (pinned to a22eb90246)