{"record":{"id":"766f86b39e842b27","repo":"jaredhanson/passport","slug":"req-logout-requires-a-callback-function","errorCode":null,"errorMessage":"req#logout requires a callback function","messagePattern":"req#logout requires a callback function","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/http/request.js","lineNumber":65,"sourceCode":"\n/**\n * Terminate an existing login session.\n *\n * @api public\n */\nreq.logout =\nreq.logOut = function(options, done) {\n  if (typeof options == 'function') {\n    done = options;\n    options = {};\n  }\n  options = options || {};\n  \n  var property = this._userProperty || 'user';\n  \n  this[property] = null;\n  if (this._sessionManager) {\n    if (typeof done != 'function') { throw new Error('req#logout requires a callback function'); }\n    \n    this._sessionManager.logOut(this, options, done);\n  } else {\n    done && done();\n  }\n};\n\n/**\n * Test if request is authenticated.\n *\n * @return {Boolean}\n * @api public\n */\nreq.isAuthenticated = function() {\n  var property = this._userProperty || 'user';\n  return (this[property]) ? true : false;\n};\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/jaredhanson/passport/blob/217018dbc46dcd4118dd6f2c60c8d97010c587f8/lib/http/request.js#L47-L83","documentation":"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.","triggerScenarios":"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).","commonSituations":"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).","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"],"exampleFix":"// before\nreq.logout();\nres.redirect('/');\n// after\nreq.logout(function(err) {\n  if (err) { return next(err); }\n  res.redirect('/');\n});","handlingStrategy":"type-guard","validationCode":"if (typeof callback !== 'function') {\n  throw new TypeError('req.logout requires a callback function argument');\n}","typeGuard":"function isFn(x) { return typeof x === 'function'; }\n// usage: if (!isFn(cb)) { /* fix call site before calling req.logout */ }","tryCatchPattern":"app.get('/logout', function(req, res, next) {\n  try {\n    req.logout(function(err) {\n      if (err) { return next(err); }\n      res.redirect('/');\n    });\n  } catch (e) { next(e); }\n});","preventionTips":["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"],"tags":["passport","callback-required","logout","session"],"backgroundTag":"missing-callback-argument","analyzedSha":"217018dbc46dcd4118dd6f2c60c8d97010c587f8","analyzedAt":"2026-08-31T21:59:48.726Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}