Server logs "User not found" but client doesn't receive the error. #727

Closed
opened 2026-03-13 08:01:46 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @Nagalsky on GitHub (Feb 23, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

When using the forgot password flow with a non-existent email:

  • Server logs "ERROR [Better Auth]: Reset Password: User not found"
  • Client receives a 200 response with { status: true } but no error message
  • No way to surface the error to the client without compromising security best practices

Current vs. Expected behavior

  • A way to show secure feedback ("If an account exists...") while still accessing error details client-side
  • OR: Configurable option to modify forgot-password error responses without exposing user existence

What version of Better Auth are you using?

1.1.19

Provide environment information

- Apple M1 Max maxOS Sonoma
- Browser Chrome

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

Client

Auth config (if applicable)

import { betterAuth, BetterAuthOptions } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { admin } from "better-auth/plugins";
import prisma from "./prisma";
import { resend } from "./resend";

export const auth = betterAuth({
  appName: "restaurant-menu-management",
  database: prismaAdapter(prisma, {
    provider: "postgresql",
  }),
  plugins: [
    admin({
      adminRole: ["admin", "superAdmin"],
    }),
  ],
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
      redirectURI: `${process.env.BETTER_AUTH_URL}/api/auth/callback/google`,
    },
  },
  emailAndPassword: {
    enabled: true,
    autoSignIn: true,
    minPasswordLength: 8,
    maxPasswordLength: 20,
    requireEmailVerification: true,
    sendResetPassword: async ({ user, url }) => {
      await resend.emails.send({
        from: process.env.RESEND_EMAIL_FROM!,
        to: user.email,
        subject: "Reset your password",
        html: `Click the link to reset your password: ${url}`,
      });
    },
  },
  emailVerification: {
    sendOnSignUp: true,
    autoSignInAfterVerification: true,
    sendVerificationEmail: async ({ user, url }) => {
      await resend.emails.send({
        from: process.env.RESEND_EMAIL_FROM!,
        to: user.email,
        subject: "Email Verification",
        html: `Click the link to verify your email: ${url}`,
      });
    },
  },
} satisfies BetterAuthOptions);

export type Session = typeof auth.$Infer.Session;

Additional context

const onSubmit = async (values: z.infer<typeof ForgotPasswordSchema>) => {
    try {
      await authClient.forgetPassword({
        email: values.email,
        redirectTo: "/reset-password",
        fetchOptions: {
          onResponse: () => {
            setLoading(false);
          },
          onRequest: () => {
            resetState();
            setLoading(true);
          },
          onSuccess: () => {
            setSuccess("Reset password link has been sent");
          },
          onError: (ctx) => {
            setError(ctx.error.message);
          },
        },
      });
    } catch (error) {
      setError(
        error instanceof Error ? error.message : "An unknown error occurred",
      );
    }
  };

No response

Originally created by @Nagalsky on GitHub (Feb 23, 2025). ### Is this suited for github? - [ ] Yes, this is suited for github ### To Reproduce When using the forgot password flow with a non-existent email: - Server logs "ERROR [Better Auth]: Reset Password: User not found" - Client receives a 200 response with `{ status: true }` but no error message - No way to surface the error to the client without compromising security best practices ### Current vs. Expected behavior - A way to show secure feedback ("If an account exists...") while still accessing error details client-side - OR: Configurable option to modify forgot-password error responses without exposing user existence ### What version of Better Auth are you using? 1.1.19 ### Provide environment information ```bash - Apple M1 Max maxOS Sonoma - Browser Chrome ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript import { betterAuth, BetterAuthOptions } from "better-auth"; import { prismaAdapter } from "better-auth/adapters/prisma"; import { admin } from "better-auth/plugins"; import prisma from "./prisma"; import { resend } from "./resend"; export const auth = betterAuth({ appName: "restaurant-menu-management", database: prismaAdapter(prisma, { provider: "postgresql", }), plugins: [ admin({ adminRole: ["admin", "superAdmin"], }), ], socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, redirectURI: `${process.env.BETTER_AUTH_URL}/api/auth/callback/google`, }, }, emailAndPassword: { enabled: true, autoSignIn: true, minPasswordLength: 8, maxPasswordLength: 20, requireEmailVerification: true, sendResetPassword: async ({ user, url }) => { await resend.emails.send({ from: process.env.RESEND_EMAIL_FROM!, to: user.email, subject: "Reset your password", html: `Click the link to reset your password: ${url}`, }); }, }, emailVerification: { sendOnSignUp: true, autoSignInAfterVerification: true, sendVerificationEmail: async ({ user, url }) => { await resend.emails.send({ from: process.env.RESEND_EMAIL_FROM!, to: user.email, subject: "Email Verification", html: `Click the link to verify your email: ${url}`, }); }, }, } satisfies BetterAuthOptions); export type Session = typeof auth.$Infer.Session; ``` ### Additional context ```typescript const onSubmit = async (values: z.infer<typeof ForgotPasswordSchema>) => { try { await authClient.forgetPassword({ email: values.email, redirectTo: "/reset-password", fetchOptions: { onResponse: () => { setLoading(false); }, onRequest: () => { resetState(); setLoading(true); }, onSuccess: () => { setSuccess("Reset password link has been sent"); }, onError: (ctx) => { setError(ctx.error.message); }, }, }); } catch (error) { setError( error instanceof Error ? error.message : "An unknown error occurred", ); } }; ``` _No response_
GiteaMirror added the bug label 2026-03-13 08:01:46 -05:00
Author
Owner

@Bekacru commented on GitHub (Feb 25, 2025):

see this https://github.com/better-auth/better-auth/issues/884

@Bekacru commented on GitHub (Feb 25, 2025): see this https://github.com/better-auth/better-auth/issues/884
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#727