karatelabs/karate · error · JsErrorException

Map.prototype.getOrInsertComputed: callback is not a…

Error message

Map.prototype.getOrInsertComputed: callback is not a function

What it means

`Map.prototype.getOrInsertComputed(key, callback)` (upsert proposal) invokes the callback only when the key is absent, but the callback itself must be a function. Karate throws this TypeError when args[1] is missing or not a JsCallable.

Solutions

  1. Pass a function as the second argument: `map.getOrInsertComputed('k', () => compute())`
  2. If you have a plain value, use `map.getOrInsert('k', value)` instead
  3. Check that the callback variable resolves to a function, not its name/string

Example fix

// before
map.getOrInsertComputed('key', 42); // TypeError
// after
map.getOrInsertComputed('key', () => 42);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof cb !== 'function') { throw new Error('getOrInsertComputed requires a function callback'); }

Type guard

function isFn(x) { return typeof x === 'function'; }

Try / catch

try {
  m.getOrInsertComputed(key, cb);
} catch (e) {
  if (String(e.message).includes('callback is not a function')) {
    m.getOrInsert(key, cb); // maybe a plain value was intended
  } else throw e;
}

Prevention

When it happens

Trigger: `map.getOrInsertComputed('k')` without the callback; passing a value instead of a function (`map.getOrInsertComputed('k', 42)`); passing a function name string from config instead of the function itself.

Common situations: Confusing getOrInsertComputed with getOrInsert (which takes a plain value); refactors that swapped the two APIs; dynamically loaded callbacks that failed to resolve.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/ac0732645d1fc2bc. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsMapPrototype.java:162

        m.setValue(key, value);
        return value;
    }

    /**
     * Spec ES2025 upsert: {@code getOrInsertComputed(key, callbackfn)}. If the
     * key is present, returns the existing value WITHOUT invoking the callback
     * (does-not-evaluate-callbackfn-if-key-present.js). Otherwise calls
     * {@code callbackfn(canonicalKey)} (canonical-key-passed-to-callback.js)
     * and stores the result. Re-checks key presence after the callback returns
     * so a callback that mutates the map can't leave a stale insert
     * (overwrites-mutation-from-callbackfn.js).
     */
    private Object getOrInsertComputed(Context context, Object[] args) {
        JsMap m = asMap(context);
        Object key = args.length > 0 ? args[0] : Terms.UNDEFINED;
        Object cb = args.length > 1 ? args[1] : Terms.UNDEFINED;
        if (!(cb instanceof JsCallable callable)) {
            throw JsErrorException.typeError("Map.prototype.getOrInsertComputed: callback is not a function");
        }
        if (m.hasKey(key)) {
            return m.getValue(key);
        }
        // Canonical key: spec normalizes -0 to +0 before invoking callback.
        Object canonicalKey = JsMap.normalizeKey(key);
        Object value = callable.call(context, new Object[]{canonicalKey});
        // Spec: a callback that threw stops the operation. The engine signals
        // throws via {@code cc.error}; bail without inserting so post-throw
        // {@code map.has(key) === false} (check-state-after-callback-fn-throws.js).
        CoreContext cc = context instanceof CoreContext c ? c : null;
        if (cc != null && cc.isError()) {
            return Terms.UNDEFINED;
        }
        // Java-null callback returns surface to JS as undefined. Re-checking
        // map state after the callback returned: per spec, OVERWRITE any
        // entry the callback inserted at the same key
        // (overwrites-mutation-from-callbackfn.js).

View on GitHub (pinned to a22eb90246)