moeru-ai/airi · error · Error
updateUser failed
Error message
updateUser failed
What it means
Thrown by updateUserProfile when better-auth's client.updateUser returns an error. The body only includes name and/or image when those args are defined. The fallback message 'updateUser failed' is used only when the server error lacks a message. Common server-side causes: name validation failure, image URL rejected, or rate limiting.
Source
Thrown at apps/ui-server-auth/src/modules/profile.ts:129
* Update the signed-in user's display name and/or avatar.
*
* Use when:
* - Saving the "display name" form on the profile page.
*
* Expects:
* - Caller has already trimmed `name` and confirmed it's non-empty.
* - `image` is either an absolute URL or `null` (clear).
*/
export async function updateUserProfile(args: UpdateUserProfileArgs): Promise<void> {
const client = getAuthClient(args)
const body: { name?: string, image?: string | null } = {}
if (args.name !== undefined)
body.name = args.name
if (args.image !== undefined)
body.image = args.image
const { error } = await client.updateUser(body)
if (error)
throw new Error(error.message ?? 'updateUser failed')
}
/**
* Change the signed-in user's password using their current credential.
*
* Use when:
* - User is signed in and wants to rotate their password from the profile
* page (not the forgot-password email flow).
*
* Expects:
* - The user has a `credential` account; social-only users get a server-side
* error which surfaces as a thrown `Error` here.
*/
export async function changePassword(args: ChangePasswordArgs): Promise<void> {
const client = getAuthClient(args)
const { error } = await client.changePassword({
currentPassword: args.currentPassword,
newPassword: args.newPassword,View on GitHub (pinned to 27111382b4)
Solutions
- Trim name and confirm non-empty before calling (the docstring expects the caller to have done this).
- Ensure image is an absolute URL or null (null clears it); reject relative paths client-side.
- Read error.message for the server's specific reason and surface it to the form field.
- If the session lapsed, re-authenticate before retrying the update.
Defensive patterns
Strategy: validation
Validate before calling
const name = args.name?.trim()
if (args.name !== undefined && !name)
throw new Error('Display name cannot be empty.')
if (args.image !== undefined && args.image !== null) {
try { new URL(args.image) } catch { throw new Error('Image must be an absolute URL.') }
}
await updateUserProfile({ ...args, name }) Type guard
function isValidProfileUpdate(args) {
if (args.name !== undefined && !args.name.trim()) return false
if (args.image !== undefined && args.image !== null) {
try { new URL(args.image) } catch { return false }
}
return true
} Try / catch
try {
await updateUserProfile(args)
} catch (e) {
// e.message carries the server reason; map to the offending form field
} Prevention
- Trim name and reject empty before calling.
- Validate image is an absolute URL or null client-side.
- Surface server messages verbatim to the relevant field.
When it happens
Trigger: Saving the profile form with a name the server rejects (too long, banned word); passing an image that is not an absolute URL or that fails server-side upload validation; the session expired between load and save so updateUser 401s.
Common situations: User edits display name to an empty/whitespace string after the caller skipped trimming; avatar URL is relative or malformed; concurrent sign-out invalidated the session; server-side image processing failed.
Related errors
- Auth request failed (${error.status ?? 'unknown'})
- changePassword failed
- signOut failed
- Auth request failed (${response.status})
- Unexpected response
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/47c3400c6a8f8fe6.
Report an issue: GitHub.