petkaantonov/bluebird · error · TypeError

expecting a function but got %s

Error message

expecting a function but got %s

What it means

Promise.method(fn) wraps a (possibly throwing/sync) function so it always returns a promise. It validates up front that fn is a function, throwing Promise.TypeError('expecting a function but got %s'). This shifts 'not a function' failures from runtime call time to wrap time with a clear message.

Source

Thrown at src/method.js:10

"use strict";
module.exports =
function(Promise, INTERNAL, tryConvertToPromise, apiRejection, debug) {
var util = require("./util");
var ASSERT = require("./assert");
var tryCatch = util.tryCatch;

Promise.method = function (fn) {
    if (typeof fn !== "function") {
        throw new Promise.TypeError(FUNCTION_ERROR + util.classString(fn));
    }
    return function () {
        var ret = new Promise(INTERNAL);
        ret._captureStackTrace();
        ret._pushContext();
        var value = tryCatch(fn).apply(this, arguments);
        var promiseCreated = ret._popContext();
        debug.checkForgottenReturns(
            value, promiseCreated, "Promise.method", ret);
        ret._resolveFromSyncValue(value);
        return ret;
    };
};

Promise.attempt = Promise["try"] = function (fn) {
    if (typeof fn !== "function") {
        return apiRejection(FUNCTION_ERROR + util.classString(fn));
    }

View on GitHub (pinned to c220cfe480)

Solutions

  1. Ensure the argument is a function: check typeof fn === 'function' before wrapping
  2. Fix imports/typos so the identifier resolves to the intended function
  3. Pass the function reference, not an invocation: Promise.method(doWork) not Promise.method(doWork())
  4. If input may be absent, guard: fn ? Promise.method(fn) : fallbackFn

Example fix

// before
const read = Promise.method(config.reader); // undefined
// after
if (typeof config.reader !== 'function') throw new Error('reader missing');
const read = Promise.method(config.reader);
Defensive patterns

Strategy: type-guard

Validate before calling

function safeMethod(fn) {
  if (typeof fn !== 'function') throw new TypeError('Promise.method expects a function, got: ' + fn);
  return Promise.method(fn);
}

Type guard

function isCallable(fn) {
  return typeof fn === 'function';
}

Try / catch

let wrapped;
try {
  wrapped = Promise.method(handler);
} catch (e) {
  if (e instanceof Promise.TypeError) {
    console.error('handler is not a function, got:', typeof handler);
    wrapped = () => Promise.reject(e);
  } else throw e;
}

Prevention

When it happens

Trigger: Promise.method(undefined/null/string/object) — passing an undefined handler due to failed import, passing the result of fn() instead of fn, passing an object property that doesn't exist, or passing a class where an instance method was intended.

Common situations: Refactor renamed the wrapped function leaving undefined; passing this.method unbound vs bound confusion; loading handlers from config/registry that returned nothing; interop where a module default export is an object not a function.

Related errors


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