express-session
semver
>=1.17.0 <2.0.0postconditions15functions7last verified2026-06-24coverage score100%Postconditions: what we check
- session · missing-secreterrorWhensession() is called without a secret optionThrows
TypeError: secret option required for sessionsRequired handlingCaller MUST provide a secret string or array of strings. This is a startup-time configuration error — the middleware will throw synchronously and the Express app will fail to start.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - session · store-errorerrorWhenThe session store emits an error (e.g., Redis connection failure, store.get/set/destroy fails)Throws
Error — forwarded to Express error handler via next(err)Required handlingApplication MUST register an Express error handler (4-argument middleware) to handle store errors. Without it, store failures will cause unhandled errors or 500 responses. Consider using store's reconnect/retry logic to handle transient failures.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - session · session-not-saved-without-changesinfoWhenSession data is not modified during the request and saveUninitialized: false is setReturnsSession is not saved to the store. No Set-Cookie header is sent.Required handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- session · successinfoWhenSession middleware initializes or resumes a session successfullyReturnsreq.session is populated with session data. req.session.id and req.session.cookie are set.Required handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- req.session.destroy · destroy-callback-error-uncheckedwarningWhenreq.session.destroy(callback) called but callback does not check the err argument. Store errors from Redis disconnect, PostgreSQL connection loss, or any persistent store failure are silently swallowed.Throws
Store-dependent errors passed as first argument to callback: Redis: ReplyError (READONLY, WRONGTYPE, connection lost) PostgreSQL: Error from pg (connection terminated, relation does not exist) Generic: Error('could not destroy session') from custom storesRequired handlingCaller MUST check err in the destroy callback. The pattern: req.session.destroy(function(err) { if (err) { /* handle */ } ... }) Without checking err: store failures are silently ignored, the session may persist in the store (user not actually logged out from server side), and monitoring systems never see the failure. The session cookie is cleared on the client regardless — creating a split-brain where the client thinks the session is gone but the store still has it.costmediumin prodsilent failureusers seedegraded performancevisibilitysilent - req.session.destroy · destroy-no-callbackerrorWhenreq.session.destroy() called without any callback. Store errors have no handler at all. The destroy operation is fire-and-forget with no way to react to failure.ReturnsNo value returned that indicates success or failure. Store errors are silently swallowed. In Node.js environments without a global uncaughtException handler, unhandled errors in store callbacks may go completely unnoticed.Required handlingAlways pass a callback to req.session.destroy(). Even a minimal error logger is better than no callback. In redirect-after-logout flows, the redirect MUST happen inside the callback — not after it — to ensure the session is actually destroyed before the user is redirected.costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
- req.session.regenerate · regenerate-callback-error-uncheckederrorWhenreq.session.regenerate(callback) called but callback does not check err. If the store fails to destroy the old session, the error is silently ignored. The new session is still created (store.generate() always runs regardless of err in the destroy step), but the old session may persist in the store.Throws
Store-dependent errors passed as first argument to callback: Same error types as destroy: Redis ReplyError, PostgreSQL connection errors. Error from store.destroy() when the old session cannot be removed.Required handlingCaller MUST check err in the regenerate callback. If err is present after login, the regeneration failed and the session fixation defense may be incomplete. Minimum required: if (err) { return next(err); } // abort login, don't proceed with authenticated state Never call next() or redirect without checking err — doing so can leave the user authenticated on a compromised session ID.costhighin prodsilent failureusers seedegraded performancevisibilitysilent - req.session.save · save-callback-error-uncheckederrorWhenreq.session.save(callback) called explicitly (e.g., before redirect) but callback does not check err. If the session store fails (Redis timeout, DB write failure), the session data is lost and the redirect proceeds as if the save succeeded.Throws
Store-dependent errors: Redis ReplyError (READONLY, OOM, connection lost), PostgreSQL write errors, or any error thrown by store.set() implementation.Required handlingCaller MUST check err in the save callback. Redirect flow pattern: req.session.save(function(err) { if (err) return next(err); res.redirect('/dashboard'); }); Proceeding with the redirect without checking err means the user's session data (e.g., userId, role, cart) may not be persisted, causing authentication failures or data loss on the next request.costhighin prodsilent failureusers seedegraded performancevisibilitysilent - req.session.save · save-before-redirect-missingwarningWhenSession data is modified and res.redirect() is called without first calling req.session.save(). The automatic save triggered at response end may not fire before the redirect response is sent in all frameworks/middleware configurations.ReturnsThe redirect response is sent immediately. The session save (if it happens at all) runs asynchronously after the response. On the redirect destination, the session data may not yet be persisted, causing the next request to see stale or missing session data.Required handlingAlways call req.session.save() explicitly before res.redirect() when session data has been modified. This is documented as a known pattern in express-session README.costmediumin prodsilent failureusers seedegraded performancevisibilitysilentSources[2]
- req.session.reload · reload-session-not-founderrorWhenreq.session.reload(callback) called but the session no longer exists in the store. This occurs when: (1) session expired via TTL in Redis/DB, (2) session was destroyed by another server instance or background process, (3) store was flushed.Throws
Error: 'failed to load session' — thrown internally when store.get() returns null/undefinedRequired handlingCaller MUST check err in the reload callback. When err is 'failed to load session', the appropriate response is to redirect the user to the login page — their session is gone. In WebSocket handlers: close the connection with a 4401 code and require re-authentication. Ignoring err leaves req.session with stale data from before the reload attempt.costmediumin prodsilent failureusers seedegraded performancevisibilitysilent - req.session.reload · reload-store-errorerrorWhenreq.session.reload(callback) called but the store.get() operation fails with a store error (Redis connection failure, DB timeout) before it can determine if the session exists.Throws
Store-dependent errors: Redis ReplyError, PostgreSQL connection errors. Error propagated verbatim from store.get() to the reload callback.Required handlingCaller MUST check err in the reload callback and distinguish between 'failed to load session' (session gone — force re-login) and store connection errors (retry or fail safely).costmediumin prodimmediate exceptionusers seedegraded performancevisibilitysilentSources[3] - req.sessionStore.all · all-callback-error-uncheckederrorWhenreq.sessionStore.all(callback) called but callback does not check the err argument. Store failures (connection lost, permission denied, store does not implement all()) are silently swallowed and treated as "no sessions in store" by the admin UI.Throws
Store-dependent errors passed as first argument to callback: Redis: ReplyError (connection lost, READONLY) PostgreSQL: connection errors, relation does not exist Custom stores: TypeError if the store implementation does not provide all() (since all() is marked optional in the express-session Store interface).Required handlingCaller MUST check err in the all() callback before iterating sessions. Pattern: req.sessionStore.all(function(err, sessions) { if (err) { return next(err); } // surface to error handler, do not render empty UI // sessions may still be undefined/null on success-with-no-data — handle separately }) Admin dashboards that ignore err render an empty session list, masking infrastructure failures. Operators may incorrectly conclude "nobody is logged in" and take action (restart, scale down) that worsens the underlying outage.costmediumin prodsilent failureusers seedegraded performancevisibilitysilent - req.sessionStore.all · all-method-not-implementederrorWhenreq.sessionStore.all(callback) called against a store implementation that does not provide the all() method. all() is marked Optional in the express-session Store interface — many third-party stores (connect-pg-simple older versions, some Redis adapters) do not implement it.Throws
TypeError: req.sessionStore.all is not a functionRequired handlingCaller MUST either (1) check typeof req.sessionStore.all === 'function' before invoking, or (2) wrap the call in try/catch to handle the TypeError. Without this guard, admin endpoints crash with a 500 when deployed against a store that omits all(), even if the same code worked in development against MemoryStore (which does implement all()).costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2] - req.sessionStore.clear · clear-callback-error-uncheckederrorWhenreq.sessionStore.clear(callback) called but callback does not check err. The store may have failed mid-clear (Redis SCAN/DEL partial failure, PostgreSQL TRUNCATE rolled back, network split). The caller proceeds as if all sessions were destroyed.Throws
Store-dependent errors passed as first argument to callback: Redis: ReplyError (READONLY during failover, connection lost mid-SCAN) PostgreSQL: TransactionRollbackError, permission errors on TRUNCATE Custom stores: any error from the underlying bulk-delete operation.Required handlingCaller MUST check err in the clear() callback. In security-incident response, an unchecked err means the runbook says "revoked all sessions" but compromised sessions remain valid in the store. Pattern: req.sessionStore.clear(function(err) { if (err) { auditLog.failure('clear', err); return next(err); } auditLog.success('clear'); }) Skipping the err check creates a split-brain between the audit log (claims success) and the store (still holding sessions) — the most dangerous failure mode in incident response.costhighin prodsilent failureusers seesecurity breachvisibilitysilentSources[2] - req.sessionStore.clear · clear-method-not-implementederrorWhenreq.sessionStore.clear(callback) called against a store implementation that does not provide the clear() method. clear() is marked Optional — many production stores (some connect-redis configurations with namespaced keys, custom enterprise stores) omit it to prevent accidental mass-revocation.Throws
TypeError: req.sessionStore.clear is not a functionRequired handlingCaller MUST guard with typeof req.sessionStore.clear === 'function' or wrap in try/catch. In a security incident, a TypeError raised here means the revoke-all-sessions runbook silently failed — operators may believe the mitigation ran when no sessions were actually revoked.costhighin prodimmediate exceptionusers seesecurity breachvisibilityvisibleSources[2]
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
Source code
- [1]github.com/expressjs/session/blobexpressjs/session · README.md
- [2]raw.githubusercontent.com/expressjs/session/masterexpressjs/session · README.md
- [3]github.com/expressjs/session/blobexpressjs/session · session.js
- [4]github.com/expressjs/session/blobexpressjs/session · store.js
- [5]github.com/expressjs/session/blobexpressjs/session · index.js
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources: express-session
Official Documentation
Research Date: 2026-02-26
Need a different package?
Request a profile