sendVerificationEmail triggered instead of sendChangeEmailVerification #1158

Closed
opened 2026-03-13 08:25:32 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @Nicolab on GitHub (May 5, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Change the email with a authenticated user. Look the mail, is not sendChangeEmailVerificationtriggered.

On frontend:

await authClient.changeEmail({
      callbackURL: '/manager/settings/account',
      newEmail: data.email,
    }, {
//...
})

### Current vs. Expected behavior

sendVerificationEmail triggered instead of sendChangeEmailVerification 

### What version of Better Auth are you using?

1.2.7

### Provide environment information

```bash
- Docker (latest Ubuntu LTS)

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  secondaryStorage: lruSecondaryStorage,
  database: mongodbAdapter(db),
  emailAndPassword: {
    sendResetPassword,
    enabled: true,
    autoSignIn: false,
    requireEmailVerification: false,
    minPasswordLength: 8,
    maxPasswordLength: 32,
    resetPasswordTokenExpiresIn: 900, // 15 minutes
  },
  emailVerification: {
    sendVerificationEmail,
    expiresIn: isAppEnv('test') ? 2 : 3600,
    sendOnSignUp: false, // should be true or false if I send mail manually
    autoSignInAfterVerification: false,
  },
  user: {
    modelName: "users",
    changeEmail: {
      enabled: true,
      sendChangeEmailVerification,
    },
// ...
}
});

Additional context

No response

Originally created by @Nicolab on GitHub (May 5, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Change the email with a authenticated user. Look the mail, is not `sendChangeEmailVerification`triggered. On frontend: ```ts await authClient.changeEmail({ callbackURL: '/manager/settings/account', newEmail: data.email, }, { //... }) ### Current vs. Expected behavior sendVerificationEmail triggered instead of sendChangeEmailVerification ### What version of Better Auth are you using? 1.2.7 ### Provide environment information ```bash - Docker (latest Ubuntu LTS) ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ secondaryStorage: lruSecondaryStorage, database: mongodbAdapter(db), emailAndPassword: { sendResetPassword, enabled: true, autoSignIn: false, requireEmailVerification: false, minPasswordLength: 8, maxPasswordLength: 32, resetPasswordTokenExpiresIn: 900, // 15 minutes }, emailVerification: { sendVerificationEmail, expiresIn: isAppEnv('test') ? 2 : 3600, sendOnSignUp: false, // should be true or false if I send mail manually autoSignInAfterVerification: false, }, user: { modelName: "users", changeEmail: { enabled: true, sendChangeEmailVerification, }, // ... } }); ``` ### Additional context _No response_
Author
Owner

@codelonesomest commented on GitHub (Jun 16, 2025):

I got the same issue with better auth 1.2.9

@codelonesomest commented on GitHub (Jun 16, 2025): I got the same issue with better auth 1.2.9
Author
Owner

@Kinfe123 commented on GitHub (Aug 11, 2025):

It intentionally calls different mailers depending on whether the current email is verified.

  • If current email is unverified (emailVerified !== true), the email is updated immediately and, if configured, a standard verification email is sent to the new email using emailVerification.sendVerificationEmail.
  • If current email is verified (emailVerified === true), it sends an approval link to the current email using user.changeEmail.sendChangeEmailVerification. After the user approves, it switches to the new email and then sends a standard verification to the new email.
@Kinfe123 commented on GitHub (Aug 11, 2025): It intentionally calls different mailers depending on whether the current email is verified. - If current email is unverified (emailVerified !== true), the email is updated immediately and, if configured, a standard verification email is sent to the new email using emailVerification.sendVerificationEmail. - If current email is verified (emailVerified === true), it sends an approval link to the current email using user.changeEmail.sendChangeEmailVerification. After the user approves, it switches to the new email and then sends a standard verification to the new email.
Author
Owner

@ixartz commented on GitHub (Oct 13, 2025):

@Kinfe123 Instead of send approval link to the current email using user.changeEmail.sendChangeEmailVerification, it would be great if we can replace by password. Like changing password, the user needs to enter his current password.

@ixartz commented on GitHub (Oct 13, 2025): @Kinfe123 Instead of send approval link to the current email using user.changeEmail.sendChangeEmailVerification, it would be great if we can replace by password. Like changing password, the user needs to enter his current password.
Author
Owner

@Nicolab commented on GitHub (Oct 30, 2025):

@Kinfe123 Instead of send approval link to the current email using user.changeEmail.sendChangeEmailVerification, it would be great if we can replace by password. Like changing password, the user needs to enter his current password.

Your request is different from the email issue mentioned here. Maybe you should open another issue. ;)

@Nicolab commented on GitHub (Oct 30, 2025): > [@Kinfe123](https://github.com/Kinfe123) Instead of send approval link to the current email using user.changeEmail.sendChangeEmailVerification, it would be great if we can replace by password. Like changing password, the user needs to enter his current password. Your request is different from the email issue mentioned here. Maybe you should open another issue. ;)
Author
Owner

@better-auth-agent[bot] commented on GitHub (Oct 30, 2025):

It appears that when you call changeEmail, the system is still triggering your default sendVerificationEmail function instead of the custom sendChangeEmailVerification handler you provided. Here are some steps to troubleshoot and resolve the issue:

  1. Verify that your auth configuration exactly sets the changeEmail property with sendChangeEmailVerification. In your config you have a “user.changeEmail” field with the property “sendChangeEmailVerification”. Double-check that there are no typos or misplaced configuration that might cause the system to fall back on emailVerification.sendVerificationEmail [1].

  2. Ensure that the changeEmail API call is correctly wired to call user.changeEmail.sendChangeEmailVerification. Sometimes, if the changeEmail feature isn’t fully enabled or if its token flow isn’t properly distinguished from regular email verification, the default verification function could get used instead. It may be helpful to add some logging in sendChangeEmailVerification to confirm it’s being called [1].

  3. If you want to change the behavior to require the user’s current password—similar to password changes—you’ll need to implement that flow separately. As noted in the latest comment, this request differs from the email change issue. If you want to add a password check for email changes, you’ll probably have to open a new issue or feature request so the team can consider it separately [2].

  4. Finally, if the issue persists even after verifying your config, try updating to a newer patch version (if available) since internal adjustments might have been made to the email handling flows. Check your logs for additional context of which function is being called and if a fallback is happening unexpectedly [1].

Following these steps should help isolate whether it’s a configuration mishap or if further code changes are necessary.

DiagramDiscordGitHub

Diagram Join Star

@better-auth-agent[bot] commented on GitHub (Oct 30, 2025): It appears that when you call changeEmail, the system is still triggering your default sendVerificationEmail function instead of the custom sendChangeEmailVerification handler you provided. Here are some steps to troubleshoot and resolve the issue: 1. Verify that your auth configuration exactly sets the changeEmail property with sendChangeEmailVerification. In your config you have a “user.changeEmail” field with the property “sendChangeEmailVerification”. Double-check that there are no typos or misplaced configuration that might cause the system to fall back on emailVerification.sendVerificationEmail [[1]](https://github.com/better-auth/better-auth/issues/2538). 2. Ensure that the changeEmail API call is correctly wired to call user.changeEmail.sendChangeEmailVerification. Sometimes, if the changeEmail feature isn’t fully enabled or if its token flow isn’t properly distinguished from regular email verification, the default verification function could get used instead. It may be helpful to add some logging in sendChangeEmailVerification to confirm it’s being called [[1]](https://github.com/better-auth/better-auth/issues/2538). 3. If you want to change the behavior to require the user’s current password—similar to password changes—you’ll need to implement that flow separately. As noted in the latest comment, this request differs from the email change issue. If you want to add a password check for email changes, you’ll probably have to open a new issue or feature request so the team can consider it separately [[2]](https://github.com/better-auth/better-auth/issues/2197). 4. Finally, if the issue persists even after verifying your config, try updating to a newer patch version (if available) since internal adjustments might have been made to the email handling flows. Check your logs for additional context of which function is being called and if a fallback is happening unexpectedly [[1]](https://github.com/better-auth/better-auth/issues/2538). Following these steps should help isolate whether it’s a configuration mishap or if further code changes are necessary. <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1158