GoogleChrome/lighthouse · error · Error

Invalid value: Argument 'locale' must be a string

Error message

Invalid value: Argument 'locale' must be a string

What it means

The --locale flag sets the display language for Lighthouse's report. coerceLocale accepts any string value (Lighthouse deliberately does not allowlist specific locales so it can fall back, e.g., es-MX to es). This error fires only when the value is not undefined and not a string — a type violation rather than an invalid locale.

Source

Thrown at cli/cli-flags.js:432

  if (typeof value !== 'string' || !value || !fs.existsSync(path.dirname(value))) {
    throw new Error(`--output-path (${value}) cannot be written to`);
  }

  return value;
}

/**
 * Verifies value is a string, then coerces type to LH.Locale for convenience. However, don't
 * allowlist specific locales. Why? So we can support the user who requests 'es-MX' (unsupported)
 * and we'll fall back to 'es' (supported).
 * @param {unknown} value
 * @return {LH.Locale|undefined}
 */
function coerceLocale(value) {
  if (value === undefined) return;

  if (typeof value !== 'string') throw new Error(`Invalid value: Argument 'locale' must be a string`);
  return /** @type {LH.Locale} */ (value);
}

/**
 * `--extra-headers` comes in as a JSON string or a path to a JSON string, but the flag value
 * needs to be the parsed object. Load file (if necessary) and returns the parsed object.
 * @param {unknown} value
 * @return {LH.SharedFlagsSettings['extraHeaders']}
 */
function coerceExtraHeaders(value) {
  // TODO: this function does not actually verify the object type.
  if (value === undefined) return value;
  if (typeof value === 'object') return /** @type {LH.SharedFlagsSettings['extraHeaders']} */ (value);
  if (typeof value !== 'string') {
    throw new Error(`Invalid value: Argument 'extra-headers' must be a string`);
  }

  // (possibly) load and parse extra headers from JSON.

View on GitHub (pinned to 9515cd4e58)

Solutions

  1. Pass the locale as a quoted string: --locale=en or --locale=es
  2. If using the programmatic API, pass locale as a string in the flags object: {locale: 'en'}
  3. Remove the flag to use Lighthouse's default locale detection

Example fix

# before (edge case where value is non-string)
# --locale passed with a numeric value
# after
lighthouse --locale=en https://example.com
Defensive patterns

Strategy: type-guard

Validate before calling

function validateLocale(value) {
  if (value !== undefined && typeof value !== 'string') {
    throw new Error(`--locale must be a string, got ${typeof value}`);
  }
}

Type guard

/** @param {unknown} v */
function isLocaleString(v) {
  return v === undefined || typeof v === 'string';
}

Prevention

When it happens

Trigger: Passing --locale with a value that yargs resolves to a non-string type (number, boolean, object). For example, a value that parses as a number or is passed programmatically as a non-string.

Common situations: Programmatic yargs configuration passing a non-string locale; shell expansion edge cases; unusual flag syntax that causes yargs to coerce the value to a non-string type.

Related errors


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