emailOTP verifyEmail broken when useNumberId is set true #1810

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

Originally created by @c-ciobanu on GitHub (Aug 30, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Having the following config:

export const auth = betterAuth({
  database: prismaAdapter(prisma, {
    provider: "postgresql",
  }),
  plugins: [
    emailOTP({
      overrideDefaultEmailVerification: true,
    }),
  ],
  advanced: {
    database: {
      useNumberId: true,
      generateId: false,
    },
  },
});

create an OTP with authClient.emailOtp.sendVerificationOtp

then invoke authClient.emailOtp.verifyEmail with a wrong OTP and it will throw the following error:

prisma:error 
Invalid `db[model].update()` invocation in
node_modules/better-auth/dist/adapters/prisma-adapter/index.cjs:147:32

  144   );
  145 }
  146 const whereClause = convertWhereClause(model, where);
→ 147 return await db[model].update({
        where: {
      +   id: String
        },
        data: {
          value: "36343:1"
        }
      })

Argument `id` is missing.

if a correct OTP is used then it works fine even if the OTP is expired

Current vs. Expected behavior

I expect authClient.emailOtp.verifyEmail not to throw an error when invoked with a wrong OTP

What version of Better Auth are you using?

1.3.7

System info

OS: Linux Mint 21.3 (Virginia)

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

Backend, Client

Auth config (if applicable)


Additional context

No response

Originally created by @c-ciobanu on GitHub (Aug 30, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Having the following config: ```ts export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: "postgresql", }), plugins: [ emailOTP({ overrideDefaultEmailVerification: true, }), ], advanced: { database: { useNumberId: true, generateId: false, }, }, }); ``` create an OTP with `authClient.emailOtp.sendVerificationOtp` then invoke `authClient.emailOtp.verifyEmail` with a wrong OTP and it will throw the following error: ``` prisma:error Invalid `db[model].update()` invocation in node_modules/better-auth/dist/adapters/prisma-adapter/index.cjs:147:32 144 ); 145 } 146 const whereClause = convertWhereClause(model, where); → 147 return await db[model].update({ where: { + id: String }, data: { value: "36343:1" } }) Argument `id` is missing. ``` if a correct OTP is used then it works fine even if the OTP is expired ### Current vs. Expected behavior I expect `authClient.emailOtp.verifyEmail` not to throw an error when invoked with a wrong OTP ### What version of Better Auth are you using? 1.3.7 ### System info ```bash OS: Linux Mint 21.3 (Virginia) ``` ### Which area(s) are affected? (Select all that apply) Backend, Client ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the bug label 2026-03-13 09:05:05 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Aug 30, 2025):

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

This is a known issue when using useNumberId: true with Better Auth and Prisma. The error happens because the verification value's id is not correctly handled as a number in the update operation, leading to Prisma's "Argument id is missing" error when you verify with a wrong OTP. This only occurs on invalid OTP attempts because the code tries to increment the attempt count using updateVerificationValue, which expects the correct ID type for your schema.

To fix this, make sure your verification-related tables (and any table using numeric IDs) have their id fields defined as Int @id @default(autoincrement()) in your Prisma schema, not as String. After updating your schema, run prisma migrate and prisma generate to sync your database and Prisma client. This ensures the adapter passes the correct ID type to Prisma and avoids the error. See this discussion for details.

Also, there are known bugs in Better Auth's schema generator with useNumberId: true that can cause type mismatches between related fields. If you encounter referential integrity issues, you may need to manually correct your schema so all related fields use the same type (usually Int) see here.

Finally, the overrideDefaultEmailVerification option in the emailOTP plugin should be removed in Better Auth v1.3.3 and later. Configure email verification using the core emailVerification config at the top level instead see here.

Let me know if you need help with the schema changes or config!

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 (Aug 30, 2025): <!-- Greeting --> Hi @c-ciobanu! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known issue when using `useNumberId: true` with Better Auth and Prisma. The error happens because the verification value's `id` is not correctly handled as a number in the update operation, leading to Prisma's "Argument `id` is missing" error when you verify with a wrong OTP. This only occurs on invalid OTP attempts because the code tries to increment the attempt count using `updateVerificationValue`, which expects the correct ID type for your schema. To fix this, make sure your verification-related tables (and any table using numeric IDs) have their `id` fields defined as `Int @id @default(autoincrement())` in your Prisma schema, not as `String`. After updating your schema, run `prisma migrate` and `prisma generate` to sync your database and Prisma client. This ensures the adapter passes the correct ID type to Prisma and avoids the error. See [this discussion for details](https://github.com/better-auth/better-auth/discussions/3558). Also, there are known bugs in Better Auth's schema generator with `useNumberId: true` that can cause type mismatches between related fields. If you encounter referential integrity issues, you may need to manually correct your schema so all related fields use the same type (usually `Int`) [see here](https://github.com/better-auth/better-auth/issues/3800). Finally, the `overrideDefaultEmailVerification` option in the emailOTP plugin should be removed in Better Auth v1.3.3 and later. Configure email verification using the core `emailVerification` config at the top level instead [see here](https://github.com/better-auth/better-auth/issues/3570). Let me know if you need help with the schema changes or config! <!-- 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/e0cbd96c-4fbd-49d9-8515-c2ed21e7b9be?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/e0cbd96c-4fbd-49d9-8515-c2ed21e7b9be?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/e0cbd96c-4fbd-49d9-8515-c2ed21e7b9be?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/e0cbd96c-4fbd-49d9-8515-c2ed21e7b9be?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/e0cbd96c-4fbd-49d9-8515-c2ed21e7b9be?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/e0cbd96c-4fbd-49d9-8515-c2ed21e7b9be?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/e0cbd96c-4fbd-49d9-8515-c2ed21e7b9be?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/4320)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1810