{"record":{"id":"7dd197e65f35bad8","repo":"mastra-ai/mastra","slug":"authentication-failed-server-provided-message","errorCode":null,"errorMessage":"Authentication failed / server-provided message","messagePattern":"Authentication failed / server-provided message","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory-ui/src/ui/domains/auth/services/auth.ts","lineNumber":88,"sourceCode":" * session cookie is set by the response; the caller navigates afterwards.\n * Throws with the server's message so the sign-in form can display it.\n */\nasync function postBetterAuthCredentials(baseUrl: string, path: string, body: Record<string, string>): Promise<void> {\n  const res = await fetch(`${baseUrl}/auth/api/${path}`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n    credentials: 'include',\n    body: JSON.stringify(body),\n  });\n  if (!res.ok) {\n    let message = 'Authentication failed';\n    try {\n      const data = (await res.json()) as { message?: string };\n      if (data?.message) message = data.message;\n    } catch {\n      // Non-JSON error body — keep the generic message.\n    }\n    throw new Error(message);\n  }\n}\n\n/**\n * Full-page navigation after a successful credential sign-in, so the app boots\n * with the fresh session cookie. Service-level (like `redirectToLogin`) because\n * jsdom's `window.location.assign` is unforgeable in tests.\n */\nexport function navigateAfterSignIn(returnTo: string): void {\n  window.location.assign(returnTo);\n}\n\n/** Email/password sign-in against the self-hosted better-auth provider. */\nexport function signInWithPassword(baseUrl: string, input: { email: string; password: string }): Promise<void> {\n  return postBetterAuthCredentials(baseUrl, 'sign-in/email', input);\n}\n\n/** Email/password sign-up against the self-hosted better-auth provider. */","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory-ui/src/ui/domains/auth/services/auth.ts#L70-L106","documentation":"postBetterAuthCredential posts credential sign-in/sign-up requests and, when the response is not ok, throws an Error whose message is either the server-provided JSON message or a generic 'Authentication failed' default. It surfaces the backend's better-auth rejection reason (bad credentials, disabled sign-up, rate limits, etc.) to the caller.","triggerScenarios":"Calling signInWithPassword or signUpWithPassword with wrong email/password (401), sign-up when registrations are disabled (signUpDisabled), expired/blocked accounts, or any non-2xx from the auth endpoint — including non-JSON error bodies which keep the generic message.","commonSituations":"User typos their password; admin disabled sign-ups so registration fails; server behind a proxy returns an HTML error page (502/503) so the generic message appears; auth endpoint version mismatch returns unexpected status codes.","solutions":["Verify the email/password are correct; retry credentials carefully (check caps-lock, trailing spaces).","Read the thrown message: a server-provided message usually explains the exact reason (e.g. sign-up disabled).","If you get the generic 'Authentication failed', inspect the network tab for the real status/HTML body — likely a proxy or server error, not bad credentials.","For sign-up errors, confirm with the admin that registration is enabled on the server."],"exampleFix":"// before\ntry {\n  await signInWithPassword({ email, password });\n} catch (e) {\n  console.log('login broken'); // generic handling hides the server reason\n}\n\n// after\ntry {\n  await signInWithPassword({ email, password });\n} catch (e) {\n  showToast((e as Error).message); // surfaces 'Invalid email or password' etc.\n}","handlingStrategy":"try-catch","validationCode":"// client-side sanity check before the request\nif (!email.includes('@') || password.length === 0) {\n  setFieldError('Enter a valid email and password');\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await signInWithPassword({ email, password });\n} catch (e) {\n  const msg = e instanceof Error ? e.message : 'Authentication failed';\n  if (msg === 'Authentication failed') {\n    // generic: inspect network response; likely server/proxy issue\n  }\n  setFormError(msg);\n}","preventionTips":["Display the thrown message verbatim — it often contains the server's reason.","Distinguish 4xx (bad credentials) from 5xx (server issue) in the network tab.","Respect signUpDisabled flag by hiding the sign-up form up front.","Add basic client-side validation to reduce avoidable failed requests."],"tags":["auth","authentication","credentials","http"],"backgroundTag":"authentication-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}