[GH-ISSUE #6396] Clarify in the docs for phone number plugin that the User must have a respective record in Account with providerId equal to "credential" #27827

Closed
opened 2026-04-17 19:03:20 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @TheMightyDev on GitHub (Nov 28, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/6396

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

I had hard time migrating from Auth.js (v5) to Better Auth and encountered some hassles which may be worth document.

In my platform, admins pre-create accounts for users to login. Users log in with phone number and password they got sent privately.

The logical thing to do was to use the built-in phoneNumber plugin. Unfortuantely it couldn't work out of the box so while examining the source code I learned that:

  1. The user must have a record in the Account table, otherwise they couldn't authenticate. In my original setup with Auth.js the account table was literally empty - I put the password field on User.
  2. Not only they need to have a record in Account, the providerId needs to be precisely equal to "credential", as examined from the code.
  3. Perhaps a trivial thing, but the password must be set in the account model (and not directly in User model...)
// packages\better-auth\src\plugins\phone-number\index.ts line 130-178
const user = await ctx.context.adapter.findOne<UserWithPhoneNumber>({
	model: "user",
	where: [
		{
			field: "phoneNumber",
			value: phoneNumber,
		},
	],
});
if (!user) {
	throw new APIError("UNAUTHORIZED", {
		message:
			PHONE_NUMBER_ERROR_CODES.INVALID_PHONE_NUMBER_OR_PASSWORD,
	});
}
if (opts.requireVerification) {
   .....
}
// 1. It searches for the accounts the user might have
const accounts = await ctx.context.internalAdapter.findAccountByUserId(user.id);
const credentialAccount = accounts.find(
	(a) => a.providerId === "credential", // 2. It filters to get only the ones the explicitly have provider "credential"
);
if (!credentialAccount) {
	ctx.context.logger.error("Credential account not found", {
		phoneNumber,
	});
	throw new APIError("UNAUTHORIZED", {
		message:
			PHONE_NUMBER_ERROR_CODES.INVALID_PHONE_NUMBER_OR_PASSWORD,
	});
}

Current vs. Expected behavior

I would expect this to be explained directly in the docs or even in the migration guide. I never populated the accounts table - and even if I did I don't think I would expect to set providerId to be as specific as "credential". Maybe I present a rare case, but I think it's worth clarifying things in the documentation to make the migration smoother.

I would have added clarification to both the migration articles and phone number plugin.

What version of Better Auth are you using?

1.3.34

System info

{
  "system": {
    "platform": "win32",
    "arch": "x64",
    "version": "Windows 10 Home",
    "release": "10.0.19045",
    "cpuCount": 8,
    "cpuModel": "Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz",
    "totalMemory": "7.82 GB",
    "freeMemory": "0.52 GB"
  },
  "node": {
    "version": "v22.11.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "10.8.2"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "^16.0.5"
    },
    {
      "name": "react",
      "version": "^19.2.0"
    }
  ],
  "databases": [
    {
      "name": "@prisma/client",
      "version": "^6.14.0"
    }
  ],
  "betterAuth": {
    "version": "^1.3.34",
    "config": null
  }
}

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

Client, Backend

Auth config (if applicable)


Additional context

No response

Originally created by @TheMightyDev on GitHub (Nov 28, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/6396 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce I had hard time migrating from Auth.js (v5) to Better Auth and encountered some hassles which may be worth document. In my platform, admins pre-create accounts for users to login. Users log in with phone number and password they got sent privately. The logical thing to do was to use the built-in `phoneNumber` plugin. Unfortuantely it couldn't work out of the box so while examining the source code I learned that: 1. The user must have a record in the `Account` table, otherwise they couldn't authenticate. In my original setup with Auth.js the account table was literally empty - I put the `password` field on `User`. 2. Not only they need to have a record in `Account`, the `providerId` needs to be precisely equal to `"credential"`, as examined from the code. 3. Perhaps a trivial thing, but the password must be set in the account model (and not directly in User model...) ```typescript // packages\better-auth\src\plugins\phone-number\index.ts line 130-178 const user = await ctx.context.adapter.findOne<UserWithPhoneNumber>({ model: "user", where: [ { field: "phoneNumber", value: phoneNumber, }, ], }); if (!user) { throw new APIError("UNAUTHORIZED", { message: PHONE_NUMBER_ERROR_CODES.INVALID_PHONE_NUMBER_OR_PASSWORD, }); } if (opts.requireVerification) { ..... } // 1. It searches for the accounts the user might have const accounts = await ctx.context.internalAdapter.findAccountByUserId(user.id); const credentialAccount = accounts.find( (a) => a.providerId === "credential", // 2. It filters to get only the ones the explicitly have provider "credential" ); if (!credentialAccount) { ctx.context.logger.error("Credential account not found", { phoneNumber, }); throw new APIError("UNAUTHORIZED", { message: PHONE_NUMBER_ERROR_CODES.INVALID_PHONE_NUMBER_OR_PASSWORD, }); } ``` ### Current vs. Expected behavior I would expect this to be explained directly in the docs or even in the migration guide. I never populated the accounts table - and even if I did I don't think I would expect to set providerId to be as specific as `"credential"`. Maybe I present a rare case, but I think it's worth clarifying things in the documentation to make the migration smoother. I would have added clarification to both the migration articles and phone number plugin. ### What version of Better Auth are you using? 1.3.34 ### System info ```bash { "system": { "platform": "win32", "arch": "x64", "version": "Windows 10 Home", "release": "10.0.19045", "cpuCount": 8, "cpuModel": "Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz", "totalMemory": "7.82 GB", "freeMemory": "0.52 GB" }, "node": { "version": "v22.11.0", "env": "development" }, "packageManager": { "name": "npm", "version": "10.8.2" }, "frameworks": [ { "name": "next", "version": "^16.0.5" }, { "name": "react", "version": "^19.2.0" } ], "databases": [ { "name": "@prisma/client", "version": "^6.14.0" } ], "betterAuth": { "version": "^1.3.34", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Client, Backend ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the locked label 2026-04-17 19:03:20 -05:00
Author
Owner

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

Thanks for opening this issue and providing detailed context. Based on your note, the current behavior of the phoneNumber plugin requires that a user has a corresponding Account record with a providerId set to "credential" and that the password is stored in that record. This is necessary because the plugin looks up the user’s account information to validate credentials, and without a proper Account record, authentication will fail. Your feedback about including this detail—especially for users migrating from Auth.js where the Account table might be empty—is very useful. It would be great to update the migration guides and the plugin documentation to explicitly state that phone number authentication depends on an Account record with providerId "credential".

Have you run into any other migration hiccups, or is this the key issue you’d like addressed? Tag @better-auth-agent if you would like an answer from the Agent.

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3590313741 --> @better-auth-agent[bot] commented on GitHub (Nov 28, 2025): Thanks for opening this issue and providing detailed context. Based on your note, the current behavior of the phoneNumber plugin requires that a user has a corresponding Account record with a providerId set to "credential" and that the password is stored in that record. This is necessary because the plugin looks up the user’s account information to validate credentials, and without a proper Account record, authentication will fail. Your feedback about including this detail—especially for users migrating from Auth.js where the Account table might be empty—is very useful. It would be great to update the migration guides and the plugin documentation to explicitly state that phone number authentication depends on an Account record with providerId "credential". Have you run into any other migration hiccups, or is this the key issue you’d like addressed? Tag @better-auth-agent if you would like an answer from the Agent. <!-- 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)
Author
Owner

@GautamBytes commented on GitHub (Nov 29, 2025):

Will be looking into it!!

<!-- gh-comment-id:3591487722 --> @GautamBytes commented on GitHub (Nov 29, 2025): Will be looking into it!!
Author
Owner

@dosubot[bot] commented on GitHub (Feb 28, 2026):

Hi, @TheMightyDev. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You requested clarification in the phone number plugin documentation about needing an Account record with providerId set to "credential" for authentication.
  • The maintainers acknowledged this requirement and agreed to update the migration guide and plugin docs.
  • They also inquired if there were any other migration issues to address.
  • Another maintainer confirmed they would investigate further.
  • The issue was resolved with plans to update the documentation accordingly.

Next Steps:

  • Please confirm if this issue is still relevant with the latest version of better-auth.
  • If it is, you can keep the discussion open by commenting; otherwise, I will automatically close this issue in 7 days.

Thank you for your understanding and contribution!

<!-- gh-comment-id:3977364510 --> @dosubot[bot] commented on GitHub (Feb 28, 2026): Hi, @TheMightyDev. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You requested clarification in the phone number plugin documentation about needing an Account record with providerId set to "credential" for authentication. - The maintainers acknowledged this requirement and agreed to update the migration guide and plugin docs. - They also inquired if there were any other migration issues to address. - Another maintainer confirmed they would investigate further. - The issue was resolved with plans to update the documentation accordingly. **Next Steps:** - Please confirm if this issue is still relevant with the latest version of better-auth. - If it is, you can keep the discussion open by commenting; otherwise, I will automatically close this issue in 7 days. Thank you for your understanding and contribution!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#27827