{"record":{"id":"c9a40cfaedb791a3","repo":"mastra-ai/mastra","slug":"errordata-message-invalid-email-or-password","errorCode":null,"errorMessage":"${errorData.message || 'Invalid email or password'}","messagePattern":"\\$\\{errorData\\.message \\|\\| 'Invalid email or password'\\}","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"auth/better-auth/src/index.ts","lineNumber":759,"sourceCode":"   * @param email - User email\n   * @param password - User password\n   * @param request - Incoming HTTP request\n   * @returns Result with user and session cookies\n   * @throws Error if credentials are invalid\n   */\n  async signIn(email: string, password: string, request: Request): Promise<CredentialsResult<EEUser>> {\n    const headers = request?.headers ?? new Headers();\n\n    // Use asResponse: true to get the full response with Set-Cookie headers\n    const response = await this.auth.api.signInEmail({\n      body: { email, password },\n      headers,\n      asResponse: true,\n    });\n\n    if (!response.ok) {\n      const errorData = (await response.json().catch(() => ({}))) as { message?: string };\n      throw new Error(errorData.message || 'Invalid email or password');\n    }\n\n    const result = (await response.json()) as { user?: User; token?: string | null };\n\n    if (!result?.user) {\n      throw new Error('Invalid email or password');\n    }\n\n    // Extract Set-Cookie headers from Better Auth response\n    const cookies: string[] = [];\n    const setCookieHeader = response.headers.get('set-cookie');\n    if (setCookieHeader) {\n      // Split multiple cookies (they may be comma-separated or in multiple headers)\n      cookies.push(...setCookieHeader.split(/,(?=\\s*\\w+=)/));\n    }\n\n    return {\n      user: mapBetterAuthUserToEEUser(result.user),","sourceCodeStart":741,"sourceCodeEnd":777,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/auth/better-auth/src/index.ts#L741-L777","documentation":"signIn() calls Better Auth's sign-in endpoint (via auth.api.signInEmail with asResponse: true). If the HTTP response is not OK, it tries to parse a JSON body for a `message` and throws that message, defaulting to 'Invalid email or password'. This is the provider surfacing the server-side rejection of the credential pair.","triggerScenarios":"signIn({ email, password }) where auth.api.signInEmail returns response.ok === false — unknown email, wrong password, account without a password credential (OAuth-only), rate-limited or disabled account; errorData.message is used when the error body contains one.","commonSituations":"User typos credentials; user registered via social/OAuth so no password exists; test fixtures using a user never signed up in the test database; server misconfigured against a different database than where the user registered.","solutions":["Verify the email/password combination is correct and the user exists in the Better Auth database the server is connected to.","Surface the underlying errorData.message from the response body to pinpoint the actual server rejection (rate limit, disabled account, etc.).","If the user is OAuth-only, use the appropriate OAuth sign-in flow instead of email/password.","Confirm the server instance (auth option) points at the same database used at sign-up."],"exampleFix":"// before: signing in against a fresh test DB with no such user\nawait auth.signIn({ email: 'dev@example.com', password: 'hunter2' }); // throws\n\n// after: sign up first (or use seeded fixtures)\nawait auth.signUp({ email: 'dev@example.com', password: 'hunter2', name: 'Dev' });\nawait auth.signIn({ email: 'dev@example.com', password: 'hunter2' });","handlingStrategy":"try-catch","validationCode":"function isValidSignInInput(input: { email: string; password: string }): boolean {\n  return /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(input.email) && input.password.length > 0;\n}","typeGuard":"function isInvalidCredentialsError(e: unknown): e is Error {\n  return e instanceof Error && (e.message === 'Invalid email or password' || /invalid|credential/i.test(e.message));\n}","tryCatchPattern":"try {\n  await provider.signIn({ email, password });\n} catch (e) {\n  if (isInvalidCredentialsError(e)) {\n    return { ok: false, reason: 'bad-credentials' }; // do not leak which field was wrong\n  }\n  throw e;\n}","preventionTips":["Return a generic 'invalid credentials' message to users; never reveal whether email or password was wrong.","Seed test users before running sign-in flows in CI.","Handle OAuth-only accounts with social sign-in rather than email/password.","Add rate limiting/lockout handling around repeated failed sign-ins."],"tags":["authentication","credentials","better-auth","http-4xx"],"backgroundTag":"invalid-credentials","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}