petkaantonov/bluebird · error · TypeError

generatorFunction must be a function See http://goo.gl/

Error message

generatorFunction must be a function

    See http://goo.gl/MqrFmX

What it means

Promise.coroutine() wraps a generator function so it can be awaited like async/await. Because it is meant to run at 'compile time' (module load) to annotate static functions, it validates its argument synchronously and throws TypeError when generatorFunction is not a function (NOT_GENERATOR_ERROR).

Source

Thrown at src/generators.js:195

        } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {
            Promise._async.invoke(
                this._promiseFulfilled, this, maybePromise._value()
            );
        } else if (BIT_FIELD_CHECK(IS_REJECTED)) {
            Promise._async.invoke(
                this._promiseRejected, this, maybePromise._reason()
            );
        } else {
            this._promiseCancelled();
        }
    }
};

Promise.coroutine = function (generatorFunction, options) {
    //Throw synchronously because Promise.coroutine is semantically
    //something you call at "compile time" to annotate static functions
    if (typeof generatorFunction !== "function") {
        throw new TypeError(NOT_GENERATOR_ERROR);
    }
    var yieldHandler = Object(options).yieldHandler;
    var PromiseSpawn$ = PromiseSpawn;
    var stack = new Error().stack;
    return function () {
        var generator = generatorFunction.apply(this, arguments);
        var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler,
                                      stack);
        var ret = spawn.promise();
        spawn._generator = generator;
        spawn._promiseFulfilled(undefined);
        return ret;
    };
};

Promise.coroutine.addYieldHandler = function(fn) {
    if (typeof fn !== "function") {
        throw new TypeError(FUNCTION_ERROR + util.classString(fn));

View on GitHub (pinned to c220cfe480)

Solutions

  1. Pass the generator function itself: Promise.coroutine(function* () { ... })
  2. Fix the import so the identifier is defined (check for undefined before calling)
  3. If targeting modern Node, drop Promise.coroutine and use native async/await
  4. Ensure your transpiler (babel regenerator etc.) preserves generator functions
  5. Validate typeof fn === 'function' at call sites building coroutines dynamically

Example fix

// before
const gen = Promise.coroutine(myGen()); // passes generator object
// after
const wrapped = Promise.coroutine(myGen); // pass the function
const result = wrapped();
Defensive patterns

Strategy: type-guard

Validate before calling

function makeCoroutine(genFn, options) {
  if (typeof genFn !== 'function') throw new TypeError('generatorFunction must be a function, got ' + typeof genFn);
  return Promise.coroutine(genFn, options);
}

Type guard

function isGeneratorFunction(fn) {
  return typeof fn === 'function' &&
    fn.constructor && fn.constructor.name === 'GeneratorFunction';
}

Try / catch

let wrapped;
try {
  wrapped = Promise.coroutine(myGen);
} catch (e) {
  if (e instanceof Promise.TypeError) throw new Error('myGen must be a generator function, got: ' + typeof myGen);
  throw e;
}

Prevention

When it happens

Trigger: Promise.coroutine(notAFunction) — passing undefined (misnamed import), a generator object instead of the generator function itself (gen() vs gen), or a string/arbitrary value; also default imports that resolve to undefined in CommonJS/ESM interop.

Common situations: Wrong import style making the target undefined; calling Promise.coroutine(generatorInstance) instead of the function; using it on a regular (non-generator) function expecting it to work; babel/TS transforms removing generator syntax so the identifier no longer exists.

Related errors


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