karatelabs/karate · error · JsErrorException
toSorted comparator must be a function
Error message
toSorted comparator must be a function
What it means
Array.prototype.toSorted accepts either no argument or a comparator function; per spec, any other value (except undefined) must throw. Karate throws TypeError 'toSorted comparator must be a function' when args[0] is present, not null/undefined, and not a JsCallable.
Solutions
- Pass a comparator function: arr.toSorted((a, b) => a.name.localeCompare(b.name))
- Replace string key usage with a comparator that reads the key
- Drop the argument entirely for default (string) sorting
- Map the key first: arr.map(x => x.key).toSorted()
Example fix
// before
const sorted = users.toSorted('name');
// after
const sorted = users.toSorted((a, b) => a.name.localeCompare(b.name)); Defensive patterns
Strategy: type-guard
Validate before calling
if (cmp !== undefined && cmp !== null && typeof cmp !== 'function') throw new Error('comparator must be a function'); Type guard
function isComparator(x) { return x == null || typeof x === 'function'; } Try / catch
try { return arr.toSorted(cmp); } catch (e) { if (String(e.message).includes('comparator must be a function')) return arr.toSorted((a,b) => String(a).localeCompare(String(b))); throw e; } Prevention
- Remember toSorted takes a comparator function, not a key string
- Use lodash-style sortBy for key-based sorting instead
- Coerce undefined comparator explicitly before calling
When it happens
Trigger: arr.toSorted('name'); arr.toSorted(1); arr.toSorted({}); — i.e. a non-callable, non-undefined first argument to toSorted (unlike sort, passing null/undefined is tolerated here).
Common situations: Confusing toSorted with toSorted-by-key helpers from other libraries (e.g. lodash-style sortBy('field')); porting code that sorted by property name strings; accidentally passing a mapped key instead of a comparator.
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
- Array.from requires an iterable or array-like object, not
- Array.prototype.* called on null or undefined
- callback is not a function
- Cannot assign to read only property 'length' of object…
- is not iterable
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/8e47c673cdb21529.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsArrayPrototype.java:1158
if (target == null) return Terms.UNDEFINED;
int len = lengthOf(target, cc);
if (cc != null && cc.isError()) return Terms.UNDEFINED;
List<Object> result = new ArrayList<>(checkResultLength(len));
for (int k = 0; k < len; k++) {
result.add(specGet(target, String.valueOf(len - k - 1), cc));
}
return new JsArray(result);
}
/**
* Spec §23.1.3.35 Array.prototype.toSorted (ES2023). Same SortCompare as
* {@link #sort} but writes to a fresh array; source is untouched. Holes
* are read through the proto chain (treated as undefined for the sort).
*/
private Object toSorted(Context context, Object[] args) {
if (args.length > 0 && args[0] != Terms.UNDEFINED && args[0] != null
&& !(args[0] instanceof JsCallable)) {
throw JsErrorException.typeError("toSorted comparator must be a function");
}
CoreContext cc = context instanceof CoreContext cx ? cx : null;
ObjectLike target = toReceiver(context.getThisObject());
if (target == null) return Terms.UNDEFINED;
int len = lengthOf(target, cc);
if (cc != null && cc.isError()) return Terms.UNDEFINED;
List<Object> items = new ArrayList<>(checkResultLength(len));
for (int k = 0; k < len; k++) {
items.add(specGet(target, String.valueOf(k), cc));
}
JsCallable comparator = (args.length > 0 && args[0] instanceof JsCallable jc) ? jc : null;
items.sort((a, b) -> {
boolean aUndef = a == null || a == Terms.UNDEFINED;
boolean bUndef = b == null || b == Terms.UNDEFINED;
if (aUndef && bUndef) return 0;
if (aUndef) return 1;
if (bUndef) return -1;
if (comparator != null) {View on GitHub (pinned to a22eb90246)