Better-Auth sign-in broken when experimental.joins = true

When email/password sign-in is used and experimental.joins: true is enabled in the Better-Auth config, the login always fails with "Invalid email or password", even though the entered credentials are correct.

Root cause
The client (or the auth handler) is incorrectly calling the password hash function instead of the password verify function:
auth.api.signInEmail → uses emailAndPassword.password.hash
instead of emailAndPassword.password.verify

This only happens when experimental.joins: true is turned on.
Disabling experimental.joins (set to false) instantly fixes the problem.

Reproduction steps
  1. Set up Better-Auth with email & password enabled
  2. Turn on experimental.joins: true in the auth config
  3. Try to sign in with a valid, existing user account
  4. → Always get "Invalid email or password"
Logs
01:26:05.193 [app·better-auth] Hash password: **
01:26:05.213 ✖ [app·signInWithPassword] (no message)
APIError: Invalid email or password
status: 401 │ type: INVALID_EMAIL_OR_PASSWORD
body: {"code":"INVALID_EMAIL_OR_PASSWORD","message":"Invalid email or password"}

Notice the log says "Hash password" during sign-in – it should be verifying, not hashing.

Environment
  • better-auth version: 1.4.3
  • Using the new experimental joins feature (experimental.joins: true)
  • Database: kysely + postgres
Workaround
Set experimental.joins: false → sign-in works perfectly again.

Would be great if this could be fixed so we can keep using the new joins feature without breaking authentication! 🙏

Thanks!
Was this page helpful?