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

  1. Pass a comparator function: arr.toSorted((a, b) => a.name.localeCompare(b.name))
  2. Replace string key usage with a comparator that reads the key
  3. Drop the argument entirely for default (string) sorting
  4. 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

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


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)