{"record":{"id":"57b751de22b5e350","repo":"TryGhost/Ghost","slug":"could-not-fetch-user-from-the-session","errorCode":null,"errorMessage":"Could not fetch user from the session.","messagePattern":"Could not fetch user from the session\\.","errorType":"exception","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"ghost/core/core/server/services/auth/session/session-service.js","lineNumber":432,"sourceCode":"            device: deviceParts.join(', '),\n            location: await getGeolocationFromIP(ip),\n            time: formatTime(new Date())\n        };\n    }\n\n    /**\n     * sendAuthCodeToUser\n     *\n     * @param {Req} req\n     * @param {Res} res\n     * @returns {Promise<void>}\n     */\n    async function sendAuthCodeToUser(req, res) {\n        const session = await getSession(req, res);\n        cookieCsrfProtection(req, session);\n\n        if (!session.user_id) {\n            throw new BadRequestError({\n                message: 'Could not fetch user from the session.'\n            });\n        }\n\n        rotateAuthCodeChallenge(session);\n        const token = await generateAuthCodeForUser(req, res);\n\n        let user;\n        try {\n            user = await findUserById({id: session.user_id});\n        } catch (error) {\n            // User session likely doesn't contain a valid user ID\n            throw new BadRequestError({\n                message: 'Could not fetch user from the session.'\n            });\n        }\n\n        const recipient = user.get('email');","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/ghost/core/core/server/services/auth/session/session-service.js#L414-L450","documentation":"A BadRequestError from `sendAuthCodeToUser` (the MFA/auth-code send path) when the session has no `user_id`. After CSRF checks pass, the code requires an already-assigned session user to send the auth code to; a session without a bound user cannot receive one. This guards the auth-code endpoint from being called before login completes.","triggerScenarios":"Calling the send-auth-code endpoint with a session cookie that has never had a user assigned — e.g. before the credentials have been validated, after session expiry/rotation cleared the user binding, or with a freshly created empty session cookie.","commonSituations":"The client requests the auth code before submitting credentials; the session expired between login and the MFA step; a cookie from a different/old session is reused; the login flow was interrupted and the session is in a half-initialized state.","solutions":["Complete the credential step (which calls `assignUserToSession`) before requesting the auth code.","If the session is stale, restart the login flow to get a fresh session with a bound `user_id`.","Ensure the session cookie from the credential step is sent with the auth-code request.","Check that nothing between the two steps clears the cookie or rotates the session id without re-assigning the user."],"exampleFix":"// before: requesting auth code before login assigns a user\nawait api.sendAuthCode(); // session.user_id missing\n\n// after: complete credential step first, reuse its session cookie\nawait api.login({email, password}); // assigns user_id to session\nawait api.sendAuthCode(); // now bound","handlingStrategy":"validation","validationCode":"function assertSessionHasUser(session) {\n  if (!session?.user_id) {\n    throw new Error('No user bound to session; complete the credential step first');\n  }\n}","typeGuard":"const sessionHasUser = (s) => Boolean(s && s.user_id);","tryCatchPattern":"try {\n  await api.sendAuthCode();\n} catch (err) {\n  if (err.type === 'BadRequestError' && /fetch user from the session/i.test(err.message)) restartLoginFlow();\n  else throw err;\n}","preventionTips":["Call the auth-code endpoint only after credentials are validated and the session has a user_id.","Reuse the session cookie from the credential step on subsequent auth requests.","Treat session expiry as a trigger to restart the login flow."],"tags":["session","auth","mfa","security","auth-code"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}