petkaantonov/bluebird · error · TypeError

expecting a function but got %s

Error message

expecting a function but got %s

What it means

`Promise.promisify(fn)` converts a Node-style callback function into a promise-returning one; it validates that `fn` is a function and throws this TypeError otherwise. Note that a function already promisified is returned as-is rather than throwing.

Source

Thrown at src/promisify.js:282

                return makeNodePromisified(key, THIS, key,
                                           fn, suffix, multiArgs);
            });
            util.notEnumerableProp(promisified, "__isPromisified__", true);
            obj[promisifiedKey] = promisified;
        }
    }
    util.toFastProperties(obj);
    return obj;
}

function promisify(callback, receiver, multiArgs) {
    return makeNodePromisified(callback, receiver, undefined,
                                callback, null, multiArgs);
}

Promise.promisify = function (fn, options) {
    if (typeof fn !== "function") {
        throw new TypeError(FUNCTION_ERROR + util.classString(fn));
    }
    if (isPromisified(fn)) {
        return fn;
    }
    options = Object(options);
    var receiver = options.context === undefined ? THIS : options.context;
    var multiArgs = !!options.multiArgs;
    var ret = promisify(fn, receiver, multiArgs);
    util.copyDescriptors(fn, ret, propsFilter);
    return ret;
};

Promise.promisifyAll = function (target, options) {
    if (typeof target !== "function" && typeof target !== "object") {
        throw new TypeError(PROMISIFY_TYPE_ERROR);
    }
    options = Object(options);
    var multiArgs = !!options.multiArgs;

View on GitHub (pinned to c220cfe480)

Solutions

  1. Pass the function itself: `Promise.promisify(fs.readFile)`.
  2. If promisifying a method needing a receiver, use `Promise.promisify(fn, { context: obj })`.
  3. Verify the value is defined and a function before calling promisify (log typeof).

Example fix

// before
const readFile = Promise.promisify('readFile');
// after
const readFile = Promise.promisify(require('fs').readFile);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof fn !== 'function') {
  throw new TypeError('promisify expects a function, got ' + typeof fn);
}
const promisified = Promise.promisify(fn);

Type guard

const isNodeStyleFn = (v) => typeof v === 'function';

Try / catch

let promisified;
try { promisified = Promise.promisify(fn); } catch (e) {
  if (e instanceof TypeError) throw new Error('Cannot promisify: target is ' + typeof fn);
  throw e;
}

Prevention

When it happens

Trigger: `Promise.promisify(undefined)`; passing a method name string instead of the function (`Promise.promisify('readFile')`); destructuring/config lookups yielding undefined before the call.

Common situations: Wrong import shape (default vs named import) so the target is undefined; promisifying an object method loses `this` and people pass wrong values; old code paths where the module export changed.

Related errors


AI-assisted analysis of petkaantonov/bluebird@c220cfe480 (2026-09-02). Data as JSON: /api/errors/2cb007e839cced93. Report an issue: GitHub.