karatelabs/karate · error · JsErrorException
Cannot convert null or undefined to object
Error message
Cannot convert null or undefined to object
What it means
Date.prototype.toJSON uses the generic-this pattern (it can delegate to any object with a toISOString), but null and undefined have no object wrapper, so it throws this TypeError per spec §20.4.4.37 step 1. Other primitives are accepted and coerced via ToPrimitive.
Solutions
- Guard for null/undefined before serializing: only call toJSON / stringify when the value is a Date.
- Use a replacer function in JSON.stringify that maps null dates to a safe value.
- Fix the data source so the field is always a Date object or explicitly omitted.
Example fix
// before
const s = JSON.stringify({ d: maybeDate }); // TypeError if maybeDate is null via toJSON path
// after
const s = JSON.stringify({ d: maybeDate instanceof Date ? maybeDate : null }); Defensive patterns
Strategy: type-guard
Validate before calling
if (value == null) return null; // skip serialization of absent dates
Type guard
function isDateLike(v) { return v !== null && v !== undefined && typeof v === 'object'; } Try / catch
try { return JSON.stringify(payload); } catch (e) { if (e instanceof TypeError && /null or undefined/.test(e.message)) return JSON.stringify(withNullDates(payload)); throw e; } Prevention
- Normalize date fields to Date or null before serialization.
- Use a JSON.stringify replacer to handle null/undefined dates.
- Treat missing API date fields explicitly instead of letting them flow into toJSON.
When it happens
Trigger: Date.prototype.toJSON.call(null), .call(undefined), or JSON.stringify(null/undefined-derived values reaching the Date.toJSON path; also `null.toJSON()` style access routed through this prototype method.
Common situations: JSON.stringify of records where a Date field is sometimes null/undefined, API responses with missing dates, template code that assumes a field is always a Date.
Related errors
- Array.prototype.* called on null or undefined
- this is not a Date object
- invalid hint to Symbol.toPrimitive:
- Date.prototype[@@toPrimitive] called on non-object
- toISOString is not a function
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/210a58681f9ab873.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsDatePrototype.java:213
private Object toUTCString(Context context, Object[] args) {
JsDate d = requireDate(context);
if (d.isInvalid()) {
return "Invalid Date";
}
return formatUtc(d);
}
/**
* Spec Date.prototype.toJSON: works on ANY object (not just Date) per
* §21.4.4.37. ToPrimitive(this, hint Number); if Number+non-finite return null;
* else Invoke(O, "toISOString"). The unusual generic-this pattern is why
* this method does NOT use {@link #requireDate}.
*/
private Object toJSON(Context context, Object[] args) {
Object o = context.getThisObject();
if (o == null || o == Terms.UNDEFINED) {
throw JsErrorException.typeError("Cannot convert null or undefined to object");
}
CoreContext cc = cc(context);
Object tv = o;
if (o instanceof ObjectLike && cc != null) {
tv = Terms.toPrimitive(o, "number", cc);
if (cc.isError()) return null;
} else if (o instanceof JsValue jv) {
tv = jv.getJsValue();
}
if (tv instanceof Number n && !Double.isFinite(n.doubleValue())) {
return null;
}
// Direct shortcut for Date this — produce ISO string. Avoids the generic
// Invoke(O, "toISOString") path doing a redundant getMember dispatch.
if (o instanceof JsDate d) {
return formatIso(d);
}
// Invoke O.toISOString()View on GitHub (pinned to a22eb90246)