Significant-Gravitas/AutoGPT · error · Error
Failed to update email
Error message
Failed to update email
What it means
Fallback message from requestEmailChange in the profile settings EmailForm: it PUTs {email} to the Next.js route /api/auth/user and, on a non-ok response, tries to surface error.error from the JSON body, falling back to 'Failed to update email' when the body has no error field or fails to parse. Note: unlike its sibling in useAccountCard (error 30), this version does NOT .catch() the response.json() call — a non-JSON error body throws a SyntaxError here instead, shadowing this message.
Source
Thrown at autogpt_platform/frontend/src/app/(platform)/profile/(user)/settings/components/SettingsForm/components/EmailForm/useEmailForm.ts:41
// Better Auth owns the email change. For a verified user it emails a
// confirmation link to their CURRENT address and only applies the new email
// once that link is clicked (anti-takeover); for an unverified user the change
// applies immediately. Platform User.email (notifications / Stripe) then
// converges via the databaseHooks.user.update mirror in lib/auth/auth.ts — we
// deliberately do NOT write the platform email here, so it can never diverge to
// an unverified value.
async function requestEmailChange(email: string) {
const response = await fetch("/api/auth/user", {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || "Failed to update email");
}
return response.json();
}
export function useEmailForm({ user }: { user: User }) {
const { toast } = useToast();
const defaultValues = createEmailDefaultValues(user);
const currentEmail = user.email;
const [isSubmitting, setIsSubmitting] = useState(false);
const form = useForm<z.infer<typeof emailFormSchema>>({
resolver: zodResolver(emailFormSchema),
defaultValues,
mode: "onSubmit",
});
async function onSubmit(values: z.infer<typeof emailFormSchema>) {View on GitHub (pinned to 9c8bb5550f)
Solutions
- Check the PUT /api/auth/user response in DevTools — the Supabase error string (error.error) is usually shown; the generic message means the body was empty/HTML.
- If 401, sign in again before retrying.
- If 429, wait — Supabase limits email-change frequency.
- Harden requestEmailChange with response.json().catch(() => ({})) as its sibling useAccountCard already does, so non-JSON bodies produce this message instead of a SyntaxError.
Example fix
// before
const error = await response.json();
throw new Error(error.error || "Failed to update email");
// after
const error = await response.json().catch(() => ({}));
throw new Error(error.error || "Failed to update email"); Defensive patterns
Strategy: try-catch
Validate before calling
const emailSchema = z.string().email();
const parsed = emailSchema.safeParse(email);
if (!parsed.success) { /* show field error, skip submit */ } Type guard
function isEmailUpdateFailure(err: unknown): boolean {
return err instanceof Error && err.message === "Failed to update email";
} Try / catch
try {
await requestEmailChange(email);
} catch (error) {
// error.message is usually the Supabase error string; generic fallback
toast({ description: (error as Error).message, variant: "destructive" });
} Prevention
- Validate email format client-side (zod) before the PUT to avoid obvious 400s.
- Always parse error bodies defensively: response.json().catch(() => ({})) — the sibling useAccountCard shows the correct pattern.
- Debounce/disable submit to avoid Supabase rate limits on repeated attempts.
When it happens
Trigger: PUT /api/auth/user returning 400 (email already in use, invalid format), 401 (session expired), 429 (Supabase rate limit on email changes), or a non-JSON body (HTML 500 page from the route) — the last case throws a JSON parse error rather than this message.
Common situations: Changing email to one already registered; Supabase auth rate-limiting repeated change attempts; expired session in a long-open settings tab; dev misconfiguration of the auth route.
Related errors
- Failed to update email
- Authentication failed — please sign in again.
- Failed to fetch session (status: ${response.status})
- Failed to update schedule
- n8n template not found (${res.status})
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/ad54063956b853f9.
Report an issue: GitHub.