{"record":{"id":"cbee6d7e6a19e7a7","repo":"overleaf/overleaf","slug":"error-checking-confirmation-code-missing-sessio","errorCode":null,"errorMessage":"error checking confirmation code. missing ${sessionKey}","messagePattern":"error checking confirmation code\\. missing (.+?)","errorType":"http","errorClass":null,"httpStatus":422,"severity":"error","filePath":"services/web/app/src/Features/User/UserEmailsController.mjs","lineNumber":195,"sourceCode":"\n/**\n * @param {string} sessionKey\n * @param {(req: import('express').Request, user: any, email: string, affiliationOptions: any) => Promise<void>} beforeConfirmEmail\n * @returns {Promise<*>}\n */\nconst _checkConfirmationCode =\n  (sessionKey, beforeConfirmEmail) => async (req, res) => {\n    const userId = SessionManager.getLoggedInUserId(req.session)\n    const code = req.body.code\n    const user = await UserGetter.promises.getUser(userId, {\n      email: 1,\n      'emails.email': 1,\n    })\n\n    const sessionData = req.session[sessionKey]\n\n    if (!sessionData) {\n      logger.err({}, `error checking confirmation code. missing ${sessionKey}`)\n\n      return res.status(422).json({\n        message: {\n          key: 'error_performing_request',\n        },\n      })\n    }\n\n    const emailToCheck = sessionData.email\n\n    try {\n      await checkConfirmCodeRateLimiter.consume(emailToCheck, 1, {\n        method: 'email',\n      })\n    } catch (err) {\n      if (err?.remainingPoints === 0) {\n        return res.sendStatus(429)\n      } else {","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/overleaf/overleaf/blob/28ad3b03b71cb4311decdcb55c36b33ec10d72db/services/web/app/src/Features/User/UserEmailsController.mjs#L177-L213","documentation":"Guard inside the _checkConfirmationCode closure factory: the request session has no entry under the given sessionKey (e.g. pendingSecondaryEmail), meaning the user is trying to confirm a code without having started the send-code step, or their session expired/reset in between. The interpolated sessionKey identifies which flow (secondary or existing email) is missing state.","triggerScenarios":"Thrown at services/web/app/src/Features/User/UserEmailsController.mjs:195 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Return a 422 prompting the user to restart the email confirmation flow","Check for session store churn or cookie loss if this fires for users mid-flow","Make the frontend send users back to the 'add email' step when this response arrives"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"28ad3b03b71cb4311decdcb55c36b33ec10d72db","analyzedAt":"2026-09-03T02:10:22.807Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}