QuantumNous/new-api · error · Error

Failed to update settings

Error message

Failed to update settings

What it means

Thrown in the language preferences card after switching the UI language: i18n.changeLanguage is applied optimistically, then updateUserLanguage(nextLanguage) persists it; a success=false response throws the backend message or this fallback. The catch path (below the source) rolls the UI language back to previousLanguage.

Source

Thrown at web/src/features/profile/components/language-preferences-card.tsx:77

  useEffect(() => {
    setCurrentLanguage(savedLanguage)
  }, [savedLanguage])

  const handleLanguageChange = async (language: string | null) => {
    if (!language) return
    const nextLanguage = normalizeInterfaceLanguage(language)
    if (nextLanguage === currentLanguage) return

    const previousLanguage = currentLanguage
    setCurrentLanguage(nextLanguage)
    setSaving(true)
    await i18n.changeLanguage(nextLanguage)

    try {
      const response = await updateUserLanguage(nextLanguage)
      if (!response.success) {
        throw new Error(response.message || t('Failed to update settings'))
      }

      if (auth.user) {
        const existingSetting =
          typeof auth.user.setting === 'string'
            ? parseUserSettings(auth.user.setting)
            : (auth.user.setting ?? {})
        auth.setUser({
          ...auth.user,
          setting: JSON.stringify({
            ...existingSetting,
            language: nextLanguage,
          }),
        })
      }

      props.onProfileUpdate()
      toast.success(t('Language preference saved'))

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Refresh and retry — if it was session expiry, re-login makes the save succeed
  2. Verify the chosen locale is in the supported set sent by the backend (en/zh/zh-TW/fr/ru/ja/vi)
  3. Check backend logs for the user-settings update error (DB failures show there)
  4. If it persistently fails for one account, test the same save with another account to isolate user-record issues

Example fix

// before
const response = await updateUserLanguage(nextLanguage)
if (!response.success) {
  throw new Error(response.message || t('Failed to update settings'))
}
// after - rollback already happens in catch; add one retry for expired-session
let response = await updateUserLanguage(nextLanguage)
if (!response.success && /unauthor|login/i.test(response.message || '')) {
  response = await updateUserLanguage(nextLanguage) // after silent re-auth
}
if (!response.success) {
  throw new Error(response.message || t('Failed to update settings'))
}
Defensive patterns

Strategy: fallback

Validate before calling

const nextLanguage = normalizeInterfaceLanguage(language)
if (!nextLanguage || nextLanguage === currentLanguage) return
// verify nextLanguage is in the supported locale list before calling the API

Type guard

const isSupportedLocale = (l: string): boolean =>
  ['en', 'zh', 'zh-TW', 'fr', 'ru', 'ja', 'vi'].includes(l)

Try / catch

const previousLanguage = currentLanguage
setCurrentLanguage(nextLanguage)
try {
  await i18n.changeLanguage(nextLanguage)
  const response = await updateUserLanguage(nextLanguage)
  if (!response.success) throw new Error(response.message || t('Failed to update settings'))
} catch (error) {
  // rollback the optimistic UI change
  setCurrentLanguage(previousLanguage)
  await i18n.changeLanguage(previousLanguage)
  toast.error(error instanceof Error ? error.message : t('Failed to update settings'))
} finally {
  setSaving(false)
}

Prevention

When it happens

Trigger: Selecting a new interface language while the persistence call fails — session expired (401), DB write error on the user settings endpoint, or backend rejects the locale value.

Common situations: Long-idle tab where the token expired before saving; backend restarted mid-request; user record locked/updated concurrently; requesting account type that cannot store settings.

Related errors


AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15). Data as JSON: /api/errors/b19fd4cae56f4fd3. Report an issue: GitHub.