moeru-ai/airi · error · Error

updateUser failed

Error message

updateUser failed

What it means

The profile-save handler calls better-auth's authClient.updateUser({ name }) and throws when the result carries an error; this literal is only the fallback when better-auth returned an error with no message. The page catches it into profileError with an i18n fallback, so it never escapes as an unhandled rejection.

Solutions

  1. Log the full error object (status/code) from updateUser before throwing — message alone is often empty.
  2. If 401: sign in again and retry.
  3. Verify the auth client baseURL matches SERVER_URL and cookies are sent.
  4. Validate the trimmed name client-side (non-empty, sane length) before the call.

Example fix

// before
const { error } = await authClient.updateUser({ name: trimmedName })
if (error)
  throw new Error(error.message ?? 'updateUser failed')

// after
const { error } = await authClient.updateUser({ name: trimmedName })
if (error)
  throw new Error(error.message ?? `updateUser failed (${error.status ?? 'no status'} ${error.code ?? ''})`)
Defensive patterns

Strategy: try-catch

Validate before calling

const trimmedName = profileForm.name.trim()
if (!trimmedName || trimmedName.length > 100) {
  profileError.value = 'Enter a valid name'
  return
}
if (!authStore.user) {
  profileError.value = 'Session expired — sign in again'
  return
}

Try / catch

catch (error) {
  if ((error as { status?: number })?.status === 401)
    await redirectToSignIn()
  else
    profileError.value = errorMessageFrom(error) ?? t('settings.pages.account.profile.error.fallback')
}

Prevention

When it happens

Trigger: Expired session so the auth server rejects the update (401); server-side validation rejects the name (empty after trim, too long); auth server unreachable or its baseURL misconfigured relative to SERVER_URL.

Common situations: Token expiry after idle; reverse proxy stripping auth cookies; the auth app (server/apps/auth) not running in dev.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/5f97ad5fa38aa7ea. Report an issue: GitHub.

Appendix: source

Thrown at packages/stage-pages/src/pages/settings/account/account-settings-page.vue:233

}

async function handleSaveProfile(event: Event) {
  event.preventDefault()
  if (profileLoading.value || !profileDirty.value)
    return

  profileError.value = null
  profileSuccess.value = null
  profileLoading.value = true

  const trimmedName = profileForm.name.trim()

  try {
    const { error } = await authClient.updateUser({
      name: trimmedName,
    })
    if (error)
      throw new Error(error.message ?? 'updateUser failed')

    if (user.value) {
      authStore.user = {
        ...user.value,
        name: trimmedName,
      }
    }
    profileForm.name = trimmedName
    profileSuccess.value = t('settings.pages.account.profile.message.saved')
  }
  catch (error) {
    profileError.value = errorMessageFrom(error) ?? t('settings.pages.account.profile.error.fallback')
  }
  finally {
    profileLoading.value = false
  }
}

View on GitHub (pinned to 677329427f)