GoogleChrome/lighthouse · error · Error

Unsupported locale '${locale}'

Error message

Unsupported locale '${locale}'

What it means

Thrown by the internal _getLocaleMessages in the i18n format module when a locale is requested that has no registered messages (not present in LOCALE_MESSAGES) and is not the DEFAULT_LOCALE. Locales must be registered ahead of time via registerLocaleData. The default-locale case is special-cased so a stripped bundle returns {} instead of throwing.

Source

Thrown at shared/localization/format.js:417

/**
 * Returns the locale messages for the given `locale`, if they exist.
 * Throws if an unsupported locale.
 *
 * NOTE: If DEFAULT_LOCALE is requested and this is inside a bundle with locale
 * messages stripped, an empty object will be returned. Default fallbacks will need to handle that case.
 * @param {LH.Locale} locale
 * @return {import('./locales').LhlMessages}
 */
function _getLocaleMessages(locale) {
  const localeMessages = LOCALE_MESSAGES[locale];
  if (!localeMessages) {
    if (locale === DEFAULT_LOCALE) {
      // If the default locale isn't in LOCALE_MESSAGES, this is likely executing
      // in a bundle. Let the caller use the fallbacks available.
      return {};
    }
    throw new Error(`Unsupported locale '${locale}'`);
  }

  return localeMessages;
}

/**
 * Returns whether the `requestedLocale` is registered and available for use
 * @param {LH.Locale} requestedLocale
 * @return {boolean}
 */
function hasLocale(requestedLocale) {
  // The default locale is always supported through `IcuMessage.formattedDefault`.
  if (requestedLocale === DEFAULT_LOCALE) return true;

  const hasIntlSupport = Intl.NumberFormat.supportedLocalesOf([requestedLocale]).length > 0;
  const hasMessages = Boolean(LOCALE_MESSAGES[requestedLocale]);

  return hasIntlSupport && hasMessages;

View on GitHub (pinned to 9515cd4e58)

Solutions

  1. Ensure the locale's messages are loaded and registered via format.registerLocaleData(locale, messages) before formatting.
  2. Use a locale that is bundled/registered, or fall back to the default locale when the requested one is unavailable.
  3. Check format.hasLocale(locale) (or the registered set) before requesting the locale.

Example fix

// before
const out = format.formatSomeMessage(...); // with unregistered locale set

// after
await loadLocaleMessages(locale).then(msgs => format.registerLocaleData(locale, msgs));
// now formatting in `locale` is safe
Defensive patterns

Strategy: validation

Validate before calling

if (format.hasLocale(locale)) {
  format.setDefaults({locale});
} else {
  await loadAndRegisterLocale(locale); // fetch + format.registerLocaleData
}

Type guard

// format.hasLocale(requestedLocale) is the canonical guard; it returns true for
// the default locale (always supported) and for any registered locale.
const ok = format.hasLocale(locale);

Try / catch

try {
  return format.getFormatted(msg, locale);
} catch (err) {
  if (err.message.startsWith('Unsupported locale')) {
    return format.getFormatted(msg, DEFAULT_LOCALE);
  } else throw err;
}

Prevention

When it happens

Trigger: Any i18n formatting call (e.g. format) that resolves to _getLocaleMessages for a locale whose messages were never registered with format.registerLocaleData, in a context where the locale is also not the default.

Common situations: A bundle build that stripped non-default locale message JSON; calling format with a locale string that is not a supported LH.Locale; forgetting to registerLocaleData after dynamically loading a locale file.

Related errors


AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13). Data as JSON: /api/errors/0944f02f357c6eb3. Report an issue: GitHub.