karatelabs/karate · error · JsErrorException
Array.prototype.* called on null or undefined
Error message
Array.prototype.* called on null or undefined
What it means
Every Array.prototype.* method performs spec ToObject on its this value, which rejects null and undefined outright. Karate's toReceiver throws this TypeError when the receiver is null or Terms.UNDEFINED, independent of strict mode.
Solutions
- Call the method on a real array or bound object: arr.map(fn)
- Bind a receiver: Array.prototype.map.call(arr, fn)
- Guard the receiver before the call: if (x == null) ...
- Initialize the variable to [] instead of null/undefined
Example fix
// before const map = arr.map; map(fn); // this === undefined // after arr.map(fn); // or const map = arr.map.bind(arr); map(fn);
Defensive patterns
Strategy: type-guard
Validate before calling
if (receiver == null) throw new Error('receiver required for Array.prototype call'); Type guard
function isArrayReceiver(o) { return o != null && (Array.isArray(o) || typeof o === 'object'); } Try / catch
try { return Array.prototype.map.call(recv, fn); } catch (e) { if (String(e.message).includes('null or undefined')) return []; throw e; } Prevention
- Bind detached method references to their original array
- Initialize collection variables to [] rather than null
- Avoid Array.prototype.*.call(null|undefined) patterns
- Use optional chaining before invoking array methods
When it happens
Trigger: Calling any Array.prototype method (e.g. via target/receiver helpers) with this set to null or undefined — e.g. Array.prototype.map.call(null, fn), or a function invoked unbound where this is undefined in strict mode.
Common situations: Detached method references like `const m = arr.map; m(fn)`; sloppy-to-strict ported code; variables that are null because a lookup returned nothing.
Related errors
- Array.from requires an iterable or array-like object, not
- is not iterable
- Cannot assign to read only property 'length' of object…
- callback is not a function
- Reduce of empty array with no initial value
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/474c7db7faf31d50.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsArrayPrototype.java:454
: 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");
}
}
/** Spec-shape {@code O = ? ToObject(this value)}. Returns the receiver
* unchanged when it's already an {@link ObjectLike}; wraps raw Java
* Lists / arrays via {@link Terms#toObjectLike} (so a Java
* {@link java.util.ArrayList} surfaces as a {@link JsArray} sharing the
* underlying list — mutations propagate). Throws TypeError for
* {@code null} / {@code undefined} per spec — independent of strict
* mode (the spec ToObject step in every Array.prototype.* method
* rejects {@code null} / {@code undefined} directly). */
private static ObjectLike toReceiver(Object thisObj) {
if (thisObj == null || thisObj == Terms.UNDEFINED) {
throw JsErrorException.typeError("Array.prototype.* called on null or undefined");
}
ObjectLike o = thisObj instanceof ObjectLike ol ? ol : Terms.toObjectLike(thisObj);
if (o == null) {
throw JsErrorException.typeError("Array.prototype.* called on null or undefined");
}
return o;
}
private static final Object[] EMPTY_ARGS = new Object[0];
/** Spec {@code IsCallable} guard — every {@code Array.prototype.*}
* iteration method begins with a TypeError when the supplied callbackfn
* is not a function (spec FindViaPredicate / map / filter / forEach /
* every / some / reduce / reduceRight / flatMap step 1). The method
* name flows into the error so test262's
* {@code Array.prototype.map called on non-callable} style assertions
* carry the spec context. */
private static JsCallable requireCallable(Object[] args, String methodName) {View on GitHub (pinned to a22eb90246)