karatelabs/karate · error · JsErrorException
invalid hint to Symbol.toPrimitive:
Error message
invalid hint to Symbol.toPrimitive:
What it means
Date.prototype[Symbol.toPrimitive] accepts only the hints 'string', 'default', or 'number'; any other hint throws this TypeError. Karate's JS engine normalizes 'default' to string-first behavior and rejects everything else before delegating to ordinaryToPrimitive.
Solutions
- Use only 'string', 'number', or 'default' as the hint argument
- Replace direct Symbol.toPrimitive calls with explicit conversions: String(d), Number(d), d.toString()
- Normalize the hint yourself before calling: hint = ['string','number'].includes(hint) ? hint : 'default'
- Debug the caller passing the hint and fix it at the source
Example fix
// before
let s = d[Symbol.toPrimitive]('date'); // TypeError
// after
let s = d[Symbol.toPrimitive](hint === 'number' ? 'number' : 'default'); Defensive patterns
Strategy: validation
Validate before calling
function toPrimitiveHint(d, hint) {
const ok = ['string', 'number', 'default'];
if (!ok.includes(hint)) throw new TypeError('hint must be string, number, or default');
return d[Symbol.toPrimitive](hint);
} Type guard
const isValidHint = (h) => h === 'string' || h === 'number' || h === 'default';
Try / catch
let v;
try { v = d[Symbol.toPrimitive](hint); } catch (e) {
if (e instanceof TypeError && /invalid hint/.test(e.message)) v = String(d);
else throw e;
} Prevention
- Only pass 'string', 'number', or 'default' to Symbol.toPrimitive
- Prefer explicit String()/Number() conversions over raw Symbol.toPrimitive calls
- Normalize synthesized hints in metaprogramming helpers before use
- Test custom coercion utilities against all three valid hints
When it happens
Trigger: Invoking the well-known Symbol.toPrimitive directly with a fabricated hint: d[Symbol.toPrimitive]('custom'), d[Symbol.toPrimitive](''), or generic toPrimitive plumbing passing through an unexpected hint value.
Common situations: Custom primitive-coercion utilities written against V8's more forgiving internals; metaprogramming frameworks that synthesize hints; test harnesses probing engine edge cases; typos in hand-rolled coercion code.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- this is not a Date object
- Date.prototype[@@toPrimitive] called on non-object
- Cannot convert null or undefined to object
- toISOString is not a function
- toBytes() argument must be a list of numbers, got
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/72e15fb0b8b78ba1.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsDatePrototype.java:179
}
/**
* Spec §21.4.4.45 Date.prototype[@@toPrimitive](hint).
* - "string" / "default" → OrdinaryToPrimitive(this, "string")
* - "number" → OrdinaryToPrimitive(this, "number")
* - anything else → TypeError
* The "default" → "string" override is the whole point of Date having its own
* @@toPrimitive: it makes `new Date() + ""` string-concat instead of timestamp-add.
*/
private Object toPrimitive(Context context, Object[] args) {
Object hint = args.length > 0 ? args[0] : Terms.UNDEFINED;
String h;
if ("string".equals(hint) || "default".equals(hint)) {
h = "string";
} else if ("number".equals(hint)) {
h = "number";
} else {
throw JsErrorException.typeError("invalid hint to Symbol.toPrimitive: " + hint);
}
Object thisObj = context.getThisObject();
if (!(thisObj instanceof ObjectLike ol)) {
throw JsErrorException.typeError("Date.prototype[@@toPrimitive] called on non-object");
}
return Terms.ordinaryToPrimitive(ol, h, (CoreContext) context);
}
private Object toISOString(Context context, Object[] args) {
JsDate d = requireDate(context);
if (d.isInvalid()) {
throw JsErrorException.rangeError("Invalid time value");
}
return formatIso(d);
}
private Object toUTCString(Context context, Object[] args) {
JsDate d = requireDate(context);View on GitHub (pinned to a22eb90246)