[GH-ISSUE #8807] bug(email-otp): change-email doesn't trigger session signal #28520

Closed
opened 2026-04-17 19:58:26 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @SeriousMonk on GitHub (Mar 27, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/8807

Originally assigned to: @ping-maxwell on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Enable emailOTP plugin with changeEmail enabled.
  2. Follow the documentation steps to change the email using otp https://better-auth.com/docs/plugins/email-otp#usage-1
  3. Have a component using the useSession() hook and displaying the user email
  4. The component with the email does not update after the email is successfully changed

Current vs. Expected behavior

When following the procedure to change the email using an OTP described here https://better-auth.com/docs/plugins/email-otp#usage-1 the session is not revalidated after authClient.emailOtp.changeEmail method is done.

Therefore any components using the useSession() hook do not update.

It appears the same thing was happening with the emailOtp email-verification and was fixed in this PR

What version of Better Auth are you using?

1.5.5

System info

{
  "system": {
    "platform": "win32",
    "arch": "x64",
    "version": "Windows 11 Pro",
    "release": "10.0.26200",
    "cpuCount": 20,
    "cpuModel": "12th Gen Intel(R) Core(TM) i7-12700K",
    "totalMemory": "31.80 GB",
    "freeMemory": "11.96 GB"
  },
  "node": {
    "version": "v24.5.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.5.1"
  },
  "frameworks": null,
  "databases": null,
  "betterAuth": {
    "version": "Unknown",
    "config": null
  }
}

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

Client

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  plugins: [
    emailOTP({
      changeEmail: { enabled: true },
    })
  ]
});

Additional context

No response

Originally created by @SeriousMonk on GitHub (Mar 27, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/8807 Originally assigned to: @ping-maxwell on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Enable emailOTP plugin with changeEmail enabled. 2. Follow the documentation steps to change the email using otp https://better-auth.com/docs/plugins/email-otp#usage-1 3. Have a component using the useSession() hook and displaying the user email 4. The component with the email does not update after the email is successfully changed ### Current vs. Expected behavior When following the procedure to change the email using an OTP described here https://better-auth.com/docs/plugins/email-otp#usage-1 the session is not revalidated after ```authClient.emailOtp.changeEmail``` method is done. Therefore any components using the ```useSession()``` hook do not update. It appears the same thing was happening with the emailOtp email-verification and was fixed in this [PR](https://github.com/better-auth/better-auth/pull/5219) ### What version of Better Auth are you using? 1.5.5 ### System info ```bash { "system": { "platform": "win32", "arch": "x64", "version": "Windows 11 Pro", "release": "10.0.26200", "cpuCount": 20, "cpuModel": "12th Gen Intel(R) Core(TM) i7-12700K", "totalMemory": "31.80 GB", "freeMemory": "11.96 GB" }, "node": { "version": "v24.5.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.5.1" }, "frameworks": null, "databases": null, "betterAuth": { "version": "Unknown", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ plugins: [ emailOTP({ changeEmail: { enabled: true }, }) ] }); ``` ### Additional context _No response_
GiteaMirror added the lockedcredentialsbug labels 2026-04-17 19:58:26 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Mar 27, 2026):

Hi @SeriousMonk! I'm Dosu and I’m helping the better-auth team.

You're right that this is a bug, and it's the same issue that was fixed for verify-email in PR #5219.

The root cause is that the /email-otp/change-email endpoint is missing from the atomListeners in the email-otp client plugin. Currently, only /email-otp/verify-email and /sign-in/email-otp are registered to trigger the $sessionSignal.

The fix would be to add the change-email endpoint to the atomListeners, similar to what PR #5219 did for verify-email:

atomListeners: [
  {
    matcher: (path) => path === "/email-otp/verify-email",
    signal: "$sessionSignal",
  },
  {
    matcher: (path) => path === "/email-otp/change-email", // Add this
    signal: "$sessionSignal",
  },
  // ...
]

Workaround until this is fixed: manually call authClient.useSession.refetch() after changeEmail succeeds to force a session refresh.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:4145747569 --> @dosubot[bot] commented on GitHub (Mar 27, 2026): <!-- Greeting --> Hi @SeriousMonk! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> You're right that this is a bug, and it's the same issue that was fixed for `verify-email` in [PR #5219](https://github.com/better-auth/better-auth/pull/5219). The root cause is that the `/email-otp/change-email` endpoint is **missing from the atomListeners** in the [email-otp client plugin](https://github.com/better-auth/better-auth/blob/221103bce7264570c9659200e91f15ad543c8e52/packages/better-auth/src/plugins/email-otp/client.ts#L12-L18). Currently, only `/email-otp/verify-email` and `/sign-in/email-otp` are registered to trigger the `$sessionSignal`. The fix would be to add the `change-email` endpoint to the atomListeners, similar to what PR #5219 did for verify-email: ```typescript atomListeners: [ { matcher: (path) => path === "/email-otp/verify-email", signal: "$sessionSignal", }, { matcher: (path) => path === "/email-otp/change-email", // Add this signal: "$sessionSignal", }, // ... ] ``` **Workaround** until this is fixed: manually call `authClient.useSession.refetch()` after `changeEmail` succeeds to force a session refresh. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/0bbdf3fa-c278-402f-8174-e524e179fd35?feedback_type=great_response&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/0bbdf3fa-c278-402f-8174-e524e179fd35?feedback_type=irrelevant_answer&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/0bbdf3fa-c278-402f-8174-e524e179fd35?feedback_type=incorrect_sources&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/0bbdf3fa-c278-402f-8174-e524e179fd35?feedback_type=too_verbose&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/0bbdf3fa-c278-402f-8174-e524e179fd35?feedback_type=hallucination&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/0bbdf3fa-c278-402f-8174-e524e179fd35?feedback_type=bug_report&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report) | [Other](https://app.dosu.dev/response-feedback/0bbdf3fa-c278-402f-8174-e524e179fd35?feedback_type=other&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=You%27re%20right%20that%20this%20is%20a%20bug%2C%20and%20it%27s%20the%20same%20issue%20that%20was%20fixed%20for%20%60verify-email%60%20in%20%5BPR%20%235219%5D%28https%3A//github.com/better-auth/better-auth/pull/5219%29.%0A%0AThe%20root%20cause%20is%20that%20the%20%60/email-otp/change-email%60%20endpoint%20is%20%2A%2Amissing%20from%20the%20atomListeners%2A%2A%20in%20the%20%5Bemail-otp%20client%20plugin%5D%28https%3A//github.com/better-auth/better-auth/blob/221103bce7264570c9659200e91f15ad543c8e52/packages/better-auth/src/plugins/email-otp/client.ts%23L12-L18%29.%20Currently%2C%20only%20%60/email-otp/verify-email%60%20and%20%60/sign-in/email-otp%60%20are%20registered%20to%20trigger%20the%20%60%24sessionSignal%60.%0A%0AThe%20fix%20would%20be%20to%20add%20the%20%60change-email%60%20endpoint%20to%20the%20atomListeners%2C%20similar%20to%20what%20PR%20%235219%20did%20for%20verify-email%3A%0A%0A%60%60%60typescript%0AatomListeners%3A%20%5B%0A%20%20%7B%0A%20%20%20%20matcher%3A%20%28path%29%20%3D%3E%20path%20%3D%3D%3D%20%22/email-otp/verify-email%22%2C%0A%20%20%20%20signal%3A%20%22%24sessionSignal%22%2C%0A%20%20%7D%2C%0A%20%20%7B%0A%20%20%20%20matcher%3A%20%28path%29%20%3D%3E%20path%20%3D%3D%3D%20%22/email-otp/change-email%22%2C%20//%20Add%20this%0A%20%20%20%20signal%3A%20%22%24sessionSignal%22%2C%0A%20%20%7D%2C%0A%20%20//%20...%0A%5D%0A%60%60%60%0A%0A%2A%2AWorkaround%2A%2A%20until%20this%20is%20fixed%3A%20manually%20call%20%60authClient.useSession.refetch%28%29%60%20after%20%60changeEmail%60%20succeeds%20to%20force%20a%20session%20refresh.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/8807)
Author
Owner

@github-actions[bot] commented on GitHub (Apr 7, 2026):

This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.

<!-- gh-comment-id:4195715557 --> @github-actions[bot] commented on GitHub (Apr 7, 2026): This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#28520