karatelabs/karate · error · TypeError
String.prototype.valueOf requires that 'this' be a String
Error message
String.prototype.valueOf requires that 'this' be a String
What it means
This TypeError is thrown by String.prototype.valueOf when 'this' is not a String or JsString object. Unlike generic string methods that coerce any value (e.g. objects become '[object Object]'), valueOf performs a strict identity check: only actual string values are accepted. Any other coercible 'this' reaches the final throw.
Solutions
- Call valueOf on an actual string: 'x'.valueOf()
- Use String(value) instead of String.prototype.valueOf.call(value) for generic conversion
- Check typeof v === 'string' (or v instanceof JsString) before the strict call
Example fix
// before const s = String.prototype.valueOf.call(42); // TypeError // after const s = String(42);
Defensive patterns
Strategy: type-guard
Validate before calling
const isStringValue = (v) => typeof v === 'string' || v instanceof String;
Type guard
const canValueOfString = (v) => typeof v === 'string';
Try / catch
try { return String.prototype.valueOf.call(recv); } catch (e) { if (e instanceof TypeError) return String(recv); throw e; } Prevention
- Do not borrow String.prototype.valueOf as a generic conversion helper — use String(v)
- Never rely on valueOf with explicit .call/.apply receivers of unknown type
- Reserve valueOf calls for values already known to be strings
When it happens
Trigger: Calling String.prototype.valueOf.call(obj) or .apply on non-string values such as numbers, booleans, or plain objects. Methods like at() use thisString() coercion and succeed; valueOf is deliberately strict.
Common situations: Borrowing String.prototype.valueOf as a generic toObject/toString helper (a V8-era trick that does not work here); calling valueOf with .call on converted values; reflection-heavy code invoking built-ins with explicit receivers.
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
- BigInt.prototype method called on non-BigInt
- this is not a Date object
- Error.prototype.toString called on non-object
- String.raw template must be an object
- String.raw .raw must be an object
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/3f5bec18864b02c2.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsStringPrototype.java:679
private Object search(Context context, Object[] args) {
String s = thisString(context, "search");
if (args.length == 0 || args[0] == null || args[0] == Terms.UNDEFINED) {
return 0;
}
JsRegex regex = (args[0] instanceof JsRegex r) ? r : new JsRegex(argString(args, 0, context));
return regex.search(s);
}
private Object valueOf(Context context, Object[] args) {
// Spec thisStringValue: if the receiver is a String primitive or a
// wrapped JsString, return its text — else TypeError. The thisString
// helper coerces objects to "[object Object]"; for valueOf we want
// the strict identity check.
Object thisObj = context.getThisObject();
if (thisObj instanceof JsString js) return js.text;
if (thisObj instanceof String s) return s;
Terms.requireObjectCoercible(thisObj, "String.prototype.valueOf");
throw JsErrorException.typeError("String.prototype.valueOf requires that 'this' be a String");
}
private Object at(Context context, Object[] args) {
String s = thisString(context, "at");
if (args.length == 0) return Terms.UNDEFINED;
int index = argInt(args, 0, 0);
if (index < 0) {
index = s.length() + index;
}
if (index < 0 || index >= s.length()) {
return Terms.UNDEFINED;
}
return String.valueOf(s.charAt(index));
}
private Object normalize(Context context, Object[] args) {
String s = thisString(context, "normalize");
String form = (args.length > 0 && args[0] != Terms.UNDEFINED) ? argString(args, 0, context) : "NFC";View on GitHub (pinned to a22eb90246)