diff --git a/lib/shared/session-utils.js b/lib/shared/session-utils.js
--- a/lib/shared/session-utils.js
+++ b/lib/shared/session-utils.js
@@ -84,23 +84,35 @@
   );
 }
 
+// actionCurrentUserInfo can either be the CurrentUserInfo at the time the
+// recovery began (preRequestUserInfo), or the CurrentUserInfo in the action.
+// We expect that for a recovery they should be the same. The intention is to
+// make sure that the CurrentUserInfo in Redux at the time this action is
+// processed is the same as the user from whom the recovery was attempted. If
+// that user has since logged out, we should ignore the result of the recovery.
+const actionSourcesCheckedForInvalidSessionRecovery = new Set([
+  recoveryActionSources.cookieInvalidationResolutionAttempt,
+  recoveryActionSources.socketAuthErrorResolutionAttempt,
+  recoveryActionSources.appStartCookieLoggedInButInvalidRedux,
+  recoveryActionSources.appStartReduxLoggedInButInvalidCookie,
+  recoveryActionSources.refetchUserDataAfterAcknowledgment,
+  recoveryActionSources.socketNotLoggedIn,
+]);
 function invalidSessionRecovery(
   currentReduxState: AppState,
   actionCurrentUserInfo: ?CurrentUserInfo,
   authActionSource: ?AuthActionSource,
 ): boolean {
   if (
-    authActionSource !==
-      recoveryActionSources.cookieInvalidationResolutionAttempt &&
-    authActionSource !== recoveryActionSources.socketAuthErrorResolutionAttempt
+    !authActionSource ||
+    !actionSourcesCheckedForInvalidSessionRecovery.has(authActionSource)
   ) {
     return false;
   }
   invariant(
     actionCurrentUserInfo,
-    'currentUserInfo (preRequestUserInfo) should be defined when ' +
-      'COOKIE_INVALIDATION_RESOLUTION_ATTEMPT or ' +
-      'SOCKET_AUTH_ERROR_RESOLUTION_ATTEMPT login is dispatched',
+    'actionCurrentUserInfo should be passed to invalidSessionRecovery for ' +
+      `${authActionSource} login`,
   );
   if (actionCurrentUserInfo.anonymous) {
     // It's not a session recovery if the CurrentUserInfo is anonymous