karatelabs/karate · error · JsErrorException
toISOString is not a function
Error message
toISOString is not a function
What it means
Date.prototype.toJSON finishes by invoking the object's `toISOString` property. If the result of ToPrimitive is an object whose `toISOString` is missing or not callable, Karate throws this TypeError per spec step 4.b/c. It means the receiver does not actually behave like a Date.
Solutions
- Ensure the object exposes a callable toISOString, or use a real Date instance.
- Add toISOString to your mock/stub if you deliberately use Date-like objects in tests.
- Check typeof obj.toISOString === 'function' before serializing.
Example fix
// before
const fake = Object.create(Date.prototype);
JSON.stringify({ d: fake }); // TypeError: toISOString is not a function
// after
const fake = Object.create(Date.prototype);
fake.toISOString = () => new Date().toISOString(); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof (obj && obj.toISOString) !== 'function') throw new Error('receiver has no callable toISOString'); Type guard
function hasToISOString(v) { return v !== null && typeof v === 'object' && typeof v.toISOString === 'function'; } Try / catch
try { return JSON.stringify(obj); } catch (e) { if (e instanceof TypeError && /toISOString is not a function/.test(e.message)) return JSON.stringify(fallback(obj)); throw e; } Prevention
- Use real Date instances instead of Date-like mocks when serializing.
- Ensure test mocks implement the full Date surface they are used for.
- Check typeof obj.toISOString === 'function' before generic serialization.
When it happens
Trigger: Date.prototype.toJSON.call({ toISOString: 42 }), .call({}) (after numeric coercion yields an object), or a plain object inheriting Date.prototype.toJSON without defining a callable toISOString.
Common situations: Objects created via Object.create(Date.prototype) or mixin patterns, mocked Date-like objects in tests lacking toISOString, and serialization code that assumes any date-ish object has the method.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- this is not a Date object
- invalid hint to Symbol.toPrimitive:
- Date.prototype[@@toPrimitive] called on non-object
- Cannot convert null or undefined to object
- toBytes() argument must be a list of numbers, got
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/14b70ca3c633b32b.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsDatePrototype.java:245
// Invoke(O, "toISOString") path doing a redundant getMember dispatch.
if (o instanceof JsDate d) {
return formatIso(d);
}
// Invoke O.toISOString()
if (o instanceof ObjectLike ol) {
Object iso = ol.getMember("toISOString");
if (iso instanceof JsCallable jc) {
CoreContext sub = (cc == null) ? null : new CoreContext(cc, null, null);
if (sub != null) sub.thisObject = o;
Object r = jc.call(sub == null ? context : sub, new Object[0]);
if (sub != null && sub.isError() && cc != null) {
cc.updateFrom(sub);
return null;
}
return r;
}
}
throw JsErrorException.typeError("toISOString is not a function");
}
private Object getFullYear(Context context, Object[] args) {
JsDate d = requireDate(context);
if (d.isInvalid()) return Double.NaN;
return localZdt(d).getYear();
}
private Object getYear(Context context, Object[] args) {
// Annex B: getYear returns getFullYear() - 1900
JsDate d = requireDate(context);
if (d.isInvalid()) return Double.NaN;
return localZdt(d).getYear() - 1900;
}
private Object getMonth(Context context, Object[] args) {
JsDate d = requireDate(context);
if (d.isInvalid()) return Double.NaN;View on GitHub (pinned to a22eb90246)