emailOTP.sendVerificationOTP second arg request is always undefined #2122

Closed
opened 2026-03-13 09:28:54 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @ceolinwill on GitHub (Oct 14, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Add the emailOTP plugin using this config:

import { emailOTP } from "better-auth/plugins";

plugins: [
  emailOTP({
    async sendVerificationOTP({ email, otp, type }, request) {
      console.log("request:", request); // always undefined
    },
  }),
]

Current vs. Expected behavior

Current behavior:

request is always undefined.

Expected behavior:

request should include the incoming Request.

What version of Better Auth are you using?

1.3.27

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.0.0: Wed Sep 17 21:38:03 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T8112",
    "release": "25.0.0",
    "cpuCount": 8,
    "cpuModel": "Apple M2",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.08 GB"
  },
  "node": {
    "version": "v22.19.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "10.18.2"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "canary"
    },
    {
      "name": "react",
      "version": "19.2.0"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "8.16.3"
    },
    {
      "name": "@prisma/client",
      "version": "6.17.0"
    }
  ],
  "betterAuth": {
    "version": "1.3.27",
    "config": {
      "plugins": [
        {
          "name": "email-otp",
          "config": {
            "id": "email-otp",
            "endpoints": {},
            "hooks": {
              "after": [
                {}
              ]
            },
            "$ERROR_CODES": {
              "OTP_EXPIRED": "otp expired",
              "INVALID_OTP": "Invalid OTP",
              "INVALID_EMAIL": "Invalid email",
              "USER_NOT_FOUND": "User not found",
              "TOO_MANY_ATTEMPTS": "Too many attempts"
            },
            "rateLimit": [
              {
                "window": 60,
                "max": 3
              },
              {
                "window": 60,
                "max": 3
              },
              {
                "window": 60,
                "max": 3
              },
              {
                "window": 60,
                "max": 3
              }
            ]
          }
        }
      ]
    }
  }
}

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

Backend

Auth config (if applicable)


Additional context

No response

Originally created by @ceolinwill on GitHub (Oct 14, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Add the `emailOTP` plugin using this config: ```ts import { emailOTP } from "better-auth/plugins"; plugins: [ emailOTP({ async sendVerificationOTP({ email, otp, type }, request) { console.log("request:", request); // always undefined }, }), ] ``` ### Current vs. Expected behavior **Current behavior:** `request` is always undefined. **Expected behavior:** `request` should include the incoming `Request`. ### What version of Better Auth are you using? 1.3.27 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.0.0: Wed Sep 17 21:38:03 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T8112", "release": "25.0.0", "cpuCount": 8, "cpuModel": "Apple M2", "totalMemory": "16.00 GB", "freeMemory": "0.08 GB" }, "node": { "version": "v22.19.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "10.18.2" }, "frameworks": [ { "name": "next", "version": "canary" }, { "name": "react", "version": "19.2.0" } ], "databases": [ { "name": "pg", "version": "8.16.3" }, { "name": "@prisma/client", "version": "6.17.0" } ], "betterAuth": { "version": "1.3.27", "config": { "plugins": [ { "name": "email-otp", "config": { "id": "email-otp", "endpoints": {}, "hooks": { "after": [ {} ] }, "$ERROR_CODES": { "OTP_EXPIRED": "otp expired", "INVALID_OTP": "Invalid OTP", "INVALID_EMAIL": "Invalid email", "USER_NOT_FOUND": "User not found", "TOO_MANY_ATTEMPTS": "Too many attempts" }, "rateLimit": [ { "window": 60, "max": 3 }, { "window": 60, "max": 3 }, { "window": 60, "max": 3 }, { "window": 60, "max": 3 } ] } } ] } } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the plugin label 2026-03-13 09:28:54 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Oct 14, 2025):

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

This is a known issue: while the emailOTP plugin's sendVerificationOTP function is designed to accept the incoming Request as the second argument, in practice, the request argument is always undefined in current tests and usage patterns. The implementation does pass ctx.request as the second argument, but the test suite and some internal calls only provide the first argument, which means your function will not reliably receive the request object as expected in Better Auth v1.3.27. This is likely an oversight or inconsistency in how the hook is invoked across the codebase, not a misconfiguration on your end.

If you need access to the request object, you may need to work around this by accessing it from a higher context or monitor for updates/fixes in future releases. See supporting details in the plugin implementation and recent PRs.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Oct 14, 2025): <!-- Greeting --> Hi @ceolinwill! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known issue: while the emailOTP plugin's sendVerificationOTP function is designed to accept the incoming Request as the second argument, in practice, the request argument is always undefined in current tests and usage patterns. The implementation does pass ctx.request as the second argument, but the test suite and some internal calls only provide the first argument, which means your function will not reliably receive the request object as expected in Better Auth v1.3.27. This is likely an oversight or inconsistency in how the hook is invoked across the codebase, not a misconfiguration on your end. If you need access to the request object, you may need to work around this by accessing it from a higher context or monitor for updates/fixes in future releases. See supporting details in the [plugin implementation](https://github.com/better-auth/better-auth/blob/c3acb35269bb2881d30580a6bfc5a0dd4ccb8691/packages/better-auth/src/plugins/email-otp/index.ts) and [recent PRs](https://github.com/better-auth/better-auth/pull/4818). <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/d6fa116b-40d2-4479-b585-bf5c496bab2f?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d6fa116b-40d2-4479-b585-bf5c496bab2f?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d6fa116b-40d2-4479-b585-bf5c496bab2f?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d6fa116b-40d2-4479-b585-bf5c496bab2f?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d6fa116b-40d2-4479-b585-bf5c496bab2f?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d6fa116b-40d2-4479-b585-bf5c496bab2f?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d6fa116b-40d2-4479-b585-bf5c496bab2f?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&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/5300)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#2122