petkaantonov/bluebird · error · TypeError
expecting a function but got %s
Error message
expecting a function but got %s
What it means
Promise.coroutine.addYieldHandler(fn) registers a handler deciding what happens when a non-promise value is yielded inside a coroutine. It requires fn to be a function and throws TypeError('expecting a function but got %s') otherwise.
Source
Thrown at src/generators.js:213
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));
}
yieldHandlers.push(fn);
};
Promise.spawn = function (generatorFunction) {
debug.deprecated("Promise.spawn()", "Promise.coroutine()");
//Return rejected promise because Promise.spawn is semantically
//something that will be called at runtime with possibly dynamic values
if (typeof generatorFunction !== "function") {
return apiRejection(NOT_GENERATOR_ERROR);
}
var spawn = new PromiseSpawn(generatorFunction, this);
var ret = spawn.promise();
spawn._run(Promise.spawn);
return ret;
};
};
View on GitHub (pinned to c220cfe480)
Solutions
- Pass an actual function: Promise.coroutine.addYieldHandler(value => handle(value))
- Verify the identifier is a defined function before registering (typeof fn === 'function')
- Register the yield handler once at startup before creating coroutines
- Check for typos or arguments accidentally omitted in the call
Example fix
// before Promise.coroutine.addYieldHandler(thunk); // thunk undefined // after Promise.coroutine.addYieldHandler(value => value && typeof value.then === 'function' ? value : Promise.resolve(value) );
Defensive patterns
Strategy: type-guard
Validate before calling
const handler = value => Promise.resolve(value);
if (typeof handler !== 'function') throw new TypeError('yield handler must be a function');
Promise.coroutine.addYieldHandler(handler); Type guard
function isValidYieldHandler(fn) {
return typeof fn === 'function' && fn.length <= 1;
} Try / catch
try {
Promise.coroutine.addYieldHandler(myHandler);
} catch (e) {
if (String(e.message).startsWith('expecting a function')) {
console.error('myHandler is not a function:', typeof myHandler);
} else throw e;
} Prevention
- Register yield handlers at startup with a literal function argument
- Check typeof before passing dynamically selected handlers
- Document that addYieldHandler takes a function receiving the yielded value
- Avoid conditional registration paths where the handler may be undefined
When it happens
Trigger: Promise.coroutine.addYieldHandler(undefined/null/object) — typically passing a variable that is undefined due to a bad import, forgetting the callback argument, or passing the handled value instead of a handler function.
Common situations: Misconfigured imports in refactorings; conditional code paths where the handler variable was never assigned; copying examples and leaving a placeholder argument; passing a class instead of an instance method bound function.
Related errors
- generatorFunction must be a function See http://goo.gl/
- Object %s has no method '%s'
- onCancel must be a function, got: %s
- expecting a function but got %s
- the promise constructor cannot be invoked directly See
AI-assisted analysis of petkaantonov/bluebird@c220cfe480 (2026-09-02).
Data as JSON: /api/errors/607c15ebe7ae6ae6.
Report an issue: GitHub.