jaredhanson/passport · error · Error
req#logout requires a callback function
Error message
req#logout requires a callback function
What it means
Request#logout() (aliased as req.logOut) clears the user and, when a session manager is present, delegates to its logOut which needs a completion callback. Passport throws this error when the session manager is configured but the 'done' argument is not a function.
Source
Thrown at lib/http/request.js:65
/**
* Terminate an existing login session.
*
* @api public
*/
req.logout =
req.logOut = function(options, done) {
if (typeof options == 'function') {
done = options;
options = {};
}
options = options || {};
var property = this._userProperty || 'user';
this[property] = null;
if (this._sessionManager) {
if (typeof done != 'function') { throw new Error('req#logout requires a callback function'); }
this._sessionManager.logOut(this, options, done);
} else {
done && done();
}
};
/**
* Test if request is authenticated.
*
* @return {Boolean}
* @api public
*/
req.isAuthenticated = function() {
var property = this._userProperty || 'user';
return (this[property]) ? true : false;
};
View on GitHub (pinned to 217018dbc4)
Solutions
- Add a callback: req.logout(function(err) { ... }) (Express 5: req.logout(function(err) { if (err) return next(err); ... }))
- Pass options before the callback: req.logout({session: false}, cb)
- Upgrade-related: if migrating to Passport 0.6+, update all req.logout() calls to include a callback
- Verify the argument is actually a function — a mis-ordered options object triggers the throw
Example fix
// before
req.logout();
res.redirect('/');
// after
req.logout(function(err) {
if (err) { return next(err); }
res.redirect('/');
}); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof callback !== 'function') {
throw new TypeError('req.logout requires a callback function argument');
} Type guard
function isFn(x) { return typeof x === 'function'; }
// usage: if (!isFn(cb)) { /* fix call site before calling req.logout */ } Try / catch
app.get('/logout', function(req, res, next) {
try {
req.logout(function(err) {
if (err) { return next(err); }
res.redirect('/');
});
} catch (e) { next(e); }
}); Prevention
- Always pass a callback to req.logout(), especially on Passport >= 0.6 and Express 5
- Update legacy route handlers written against the old no-callback signature
- Grep for req.logout() zero-argument calls during upgrades
- Handle the callback error with next(err) instead of ignoring it
When it happens
Trigger: calling req.logout() with no callback in an app with session support, or passing a non-function as done (e.g. req.logout({session: false}) forgetting the trailing callback).
Common situations: Following pre-0.6 Passport examples where req.logout() without a callback was common; Express 5 / Passport 0.6+ made the callback effectively required for proper session clearing; calling logout inside sync handlers without next(err).
Related errors
AI-assisted analysis of jaredhanson/passport@217018dbc4 (2026-08-31).
Data as JSON: /api/errors/766f86b39e842b27.
Report an issue: GitHub.