karatelabs/karate · error · JsErrorException
Invalid array length
Error message
Invalid array length
What it means
This RangeError is thrown by Karate's JS engine when an array-like operation would produce a result length at or above the JVM-safe bound (spec ArrayCreate throws above 2^32-1; this store bound is lower and documented in TEST262.md). It exists so a lying {length: 2**32} array-like cannot OOM the JVM through map / splice / toReversed / toSorted / toSpliced.
Solutions
- Fix the receiver's length value to a realistic array size
- Ensure inputs to map/splice/toSorted etc. are real arrays, not array-likes with huge lengths
- Wrap the call in try/catch and treat RangeError as invalid input
- Validate length <= 2^32-2 before invoking array methods on array-likes
Example fix
// before
var fake = { length: 4294967295 };
Array.prototype.map.call(fake, f);
// after
var fake = { length: 4294967295 };
if (fake.length > 2147483646) throw new Error('array-like too large');
Array.prototype.map.call(fake, f); Defensive patterns
Strategy: validation
Validate before calling
if (typeof obj.length !== 'number' || obj.length < 0 || obj.length > 2147483646) throw new Error('array-like length out of safe range: ' + obj.length); Type guard
function isSafeArrayLike(o) { return o != null && typeof o.length === 'number' && Number.isInteger(o.length) && o.length >= 0 && o.length <= 2147483646; } Prevention
- Never trust a length field from external JSON — clamp it before use
- Prefer real arrays over hand-rolled array-likes
- Fuzz-test array methods with extreme length values
- Keep array-likes below Integer.MAX_VALUE - 1
When it happens
Trigger: Calling len, removed, result, items, or the newLen path of array methods on a receiver whose length coerces to Integer.MAX_VALUE (2147483647), e.g. an object with {length: 4294967295} passed to Array.prototype.map.call, or a huge new length passed to splice/unshift.
Common situations: Hand-rolled array-like objects with inflated length fields; JSON payloads with spoofed length; ported JS that relies on V8's larger limits; fuzzing or hostile scripts evaluated in Karate's embedded JS.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- array index too large for dense storage:
- Invalid array length
- Array.from requires an iterable or array-like object, not
- is not iterable
- Cannot assign to read only property 'length' of object…
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/9ffd252d85defb76.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsArrayPrototype.java:422
Number n = lenObj instanceof ObjectLike
? Terms.toNumberCoerce(lenObj, ctx)
: Terms.objectToNumber(lenObj);
if (ctx != null && ctx.isError()) return 0;
double d = n == null ? Double.NaN : n.doubleValue();
if (Double.isNaN(d) || d <= 0) return 0;
if (d >= Integer.MAX_VALUE) return Integer.MAX_VALUE;
return (int) d;
}
/** {@link #lengthOf} clamps a huge claimed length to Integer.MAX_VALUE;
* a result of that magnitude cannot be dense-allocated. The spec answer
* is RangeError (ArrayCreate §10.4.2.2 throws above 2^32-1; the store
* bound here is lower and documented in TEST262.md) — throwing it here
* keeps a lying {@code {length: 2**32}} array-like from OOMing the JVM
* through map / splice / toReversed / toSorted / toSpliced. */
private static int checkResultLength(int len) {
if (len == Integer.MAX_VALUE) {
throw JsErrorException.rangeError("Invalid array length");
}
return len;
}
/** Spec §23.1.3.34 step 4 (unshift) / §23.1.3.31 (splice): a receiver
* whose length plus the inserted count would exceed 2^53-1 throws
* TypeError before any element is moved. Reads the raw double length —
* {@link #lengthOf}'s int clamp cannot see these magnitudes. */
private static void checkLengthLimit(ObjectLike target, CoreContext ctx, int addCount) {
Object lenObj = target.getMember("length", target, ctx);
if (lenObj == null || lenObj == Terms.UNDEFINED) return;
Number n = lenObj instanceof ObjectLike
? Terms.toNumberCoerce(lenObj, ctx)
: Terms.objectToNumber(lenObj);
if (ctx != null && ctx.isError()) return;
double d = n == null ? Double.NaN : n.doubleValue();
if (d + addCount > 9007199254740991.0) { // 2^53 - 1
throw JsErrorException.typeError("Invalid array length");View on GitHub (pinned to a22eb90246)