{"record":{"id":"8567949093ace4ca","repo":"moeru-ai/airi","slug":"changepassword-failed","errorCode":null,"errorMessage":"changePassword failed","messagePattern":"changePassword failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/ui-server-auth/src/modules/profile.ts","lineNumber":151,"sourceCode":" * Change the signed-in user's password using their current credential.\n *\n * Use when:\n * - User is signed in and wants to rotate their password from the profile\n *   page (not the forgot-password email flow).\n *\n * Expects:\n * - The user has a `credential` account; social-only users get a server-side\n *   error which surfaces as a thrown `Error` here.\n */\nexport async function changePassword(args: ChangePasswordArgs): Promise<void> {\n  const client = getAuthClient(args)\n  const { error } = await client.changePassword({\n    currentPassword: args.currentPassword,\n    newPassword: args.newPassword,\n    revokeOtherSessions: args.revokeOtherSessions ?? true,\n  })\n  if (error)\n    throw new Error(error.message ?? 'changePassword failed')\n}\n\n/**\n * Sign the current user out via better-auth's `/sign-out` endpoint.\n *\n * Use when:\n * - User clicks \"Sign out\" on the profile page.\n *\n * Returns:\n * - Resolves once the better-auth session cookie has been cleared by the\n *   server. Caller is expected to navigate the user back to the sign-in\n *   page after this resolves.\n */\nexport async function signOut(args: AuthFetchBase): Promise<void> {\n  const client = getAuthClient(args)\n  const { error } = await client.signOut()\n  if (error)\n    throw new Error(error.message ?? 'signOut failed')","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/apps/ui-server-auth/src/modules/profile.ts#L133-L169","documentation":"Thrown by changePassword when better-auth's client.changePassword returns an error. The call sends currentPassword, newPassword, and revokeOtherSessions (defaulting true). The fallback 'changePassword failed' appears only when the server error has no message. A documented case: social-only users (no credential account) get a server-side error here.","triggerScenarios":"Submitting the change-password form with an incorrect currentPassword; newPassword failing server complexity rules; the user has only social/OAuth accounts and no credential to rotate; session expired mid-flow.","commonSituations":"User mistypes current password; new password violates server policy; attempting password change on an account created via Google/GitHub sign-in; rate limiting on password endpoints.","solutions":["Surface error.message to the currentPassword field — 'Invalid credentials' style messages come straight from better-auth.","For social-only users, guide them to set a password via forgot-password flow instead.","Validate newPassword against the same complexity rules client-side before submitting.","Handle revokeOtherSessions semantics: inform the user other devices will be signed out."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function meetsPasswordPolicy(pw) {\n  return typeof pw === 'string' && pw.length >= 8\n}\nif (!meetsPasswordPolicy(args.newPassword))\n  throw new Error('New password does not meet policy.')","typeGuard":null,"tryCatchPattern":"try {\n  await changePassword(args)\n} catch (e) {\n  // map e.message to the currentPassword or newPassword field\n}","preventionTips":["Mirror server password complexity rules in client validation.","For social-only accounts, route to forgot-password instead.","Warn the user that other sessions will be revoked."],"tags":["auth","profile","better-auth","password","ui-server-auth"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}