srbhr/Resume-Matcher · warning · HTTPException

Unsupported UI language: {request.ui_language}. Supported: {

Error message

Unsupported UI language: {request.ui_language}. Supported: {SUPPORTED_LANGUAGES}

What it means

A 400 HTTPException raised by update_language_config when request.ui_language is provided but not a member of SUPPORTED_LANGUAGES. The backend only accepts a fixed whitelist of UI languages and rejects anything else before saving config.

Source

Thrown at apps/backend/app/routers/config.py:321

    return LanguageConfigResponse(
        ui_language=stored.get("ui_language", legacy_language),
        content_language=stored.get("content_language", legacy_language),
        supported_languages=SUPPORTED_LANGUAGES,
    )


@router.put("/language", response_model=LanguageConfigResponse)
async def update_language_config(
    request: LanguageConfigRequest,
) -> LanguageConfigResponse:
    """Update language configuration."""
    stored = _load_config()

    # Validate and update UI language
    if request.ui_language is not None:
        if request.ui_language not in SUPPORTED_LANGUAGES:
            raise HTTPException(
                status_code=400,
                detail=f"Unsupported UI language: {request.ui_language}. Supported: {SUPPORTED_LANGUAGES}",
            )
        stored["ui_language"] = request.ui_language

    # Validate and update content language
    if request.content_language is not None:
        if request.content_language not in SUPPORTED_LANGUAGES:
            raise HTTPException(
                status_code=400,
                detail=f"Unsupported content language: {request.content_language}. Supported: {SUPPORTED_LANGUAGES}",
            )
        stored["content_language"] = request.content_language

    # Save config
    _save_config(stored)

    # Support legacy single 'language' field migration

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Send a ui_language value exactly matching one of SUPPORTED_LANGUAGES (check GET language config/options)
  2. Normalize client locales to the backend's canonical codes (e.g. 'pt-BR' -> 'pt')
  3. Omit ui_language from the request if you don't intend to change it

Example fix

// before
await api.updateLanguageConfig({ ui_language: 'en_US' })
// after
await api.updateLanguageConfig({ ui_language: 'en' })
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = await api.getSupportedLanguages()
if (uiLang && !SUPPORTED.includes(uiLang)) {
  uiLang = normalizeLocale(uiLang) // e.g. 'en_US' -> 'en'
  if (!SUPPORTED.includes(uiLang)) uiLang = SUPPORTED[0]
}

Try / catch

try {
  await api.updateLanguageConfig({ ui_language: lang })
} catch (e) {
  if (e.response?.status === 400 && String(e.response.data.detail).startsWith('Unsupported UI language')) {
    showToast(`Language ${lang} is not supported`)
  } else throw e
}

Prevention

When it happens

Trigger: PUT/POST language config with ui_language set to a code not in SUPPORTED_LANGUAGES, e.g. 'en_US' when only 'en' is supported, an empty string, or a regional variant.

Common situations: Frontend sends a locale (BCP-47 tag with region/script) that the backend whitelist does not include; language list changed between versions and client ships a now-unsupported code.

Related errors


AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28). Data as JSON: /api/errors/4e7e859e91142936. Report an issue: GitHub.