jackwener/OpenCLI · error · ArgumentError

lang must be one of: ${[...ALLOWED_LANGS].join(', ')}

Error message

lang must be one of: ${[...ALLOWED_LANGS].join(', ')}

What it means

normalizeLang validates the optional lang parameter against a fixed ALLOWED_LANGS set of BCP-47-style tags (en-us, zh-cn, ja, de, ...). The value is trimmed and lowercased first, then membership is checked; anything outside the set throws ArgumentError. Unknown or unsupported locale codes are rejected to keep the underlying site's language parameter valid.

Source

Thrown at clis/booking/search.js:73

function normalizeCurrency(value) {
  if (value == null || value === '') return '';
  const v = String(value).trim().toUpperCase();
  if (!/^[A-Z]{3}$/.test(v)) {
    throw new ArgumentError(`currency must be a 3-letter ISO code (e.g. USD, JPY, CNY), got ${JSON.stringify(value)}`);
  }
  return v;
}

const ALLOWED_LANGS = new Set([
  'en-us', 'en-gb', 'zh-cn', 'zh-tw', 'ja', 'ko', 'de', 'fr', 'es', 'it',
  'pt-br', 'pt-pt', 'ru', 'th', 'vi', 'tr', 'pl', 'nl', 'ar',
]);

function normalizeLang(value) {
  if (value == null || value === '') return '';
  const v = String(value).trim().toLowerCase();
  if (!ALLOWED_LANGS.has(v)) {
    throw new ArgumentError(`lang must be one of: ${[...ALLOWED_LANGS].join(', ')}`);
  }
  return v;
}

function hasPositiveResultCount(text) {
  const value = String(text || '').replace(/\u00a0/g, ' ');
  const resultCount = value.match(/\b([1-9][0-9,.\s]*)\s+(?:properties|property|stays|stay|hotels|hotel)\b/i);
  if (!resultCount) return false;
  const digits = resultCount[1].replace(/\D/g, '');
  return Boolean(digits) && Number(digits) > 0;
}

function buildSearchUrl({
  destination,
  checkin,
  checkout,
  adults,
  rooms,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Change the value to one of the allowed tags, e.g. 'en-us' instead of 'en', 'zh-cn' instead of 'zh'
  2. Map your app's locale to the nearest supported tag before calling (fr-CA -> fr, es-MX -> es)
  3. Trim and lowercase the value to rule out accidental case/whitespace mismatches
  4. If a needed locale is missing, extend ALLOWED_LANGS in clis/booking/search.js

Example fix

// before
const lang = 'en';
await search(page, { destination: 'Tokyo', lang });
// after
const lang = 'en-us';
await search(page, { destination: 'Tokyo', lang });
Defensive patterns

Strategy: type-guard

Validate before calling

const ALLOWED = new Set(['en-us','en-gb','zh-cn','zh-tw','ja','ko','de','fr','es','it','pt-br','pt-pt','ru','th','vi','tr','pl','nl','ar']);
function normalizeLangSafe(v) {
  if (v == null || v === '') return '';
  const s = String(v).trim().toLowerCase();
  if (!ALLOWED.has(s)) throw new Error(`unsupported lang: ${v}`);
  return s;
}

Type guard

function isSupportedLang(v) {
  const s = String(v ?? '').trim().toLowerCase();
  return s === '' || ['en-us','en-gb','zh-cn','zh-tw','ja','ko','de','fr','es','it','pt-br','pt-pt','ru','th','vi','tr','pl','nl','ar'].includes(s);
}

Try / catch

try {
  await search(page, { destination, lang });
} catch (e) {
  if (/lang must be one of/.test(e.message)) {
    lang = mapToSupportedLang(lang); // e.g. 'en' -> 'en-us'
  } else throw e;
}

Prevention

When it happens

Trigger: Passing lang values like 'en', 'en-US-x-variant', 'zh', 'zh-Hans', 'pt', 'fr-CA', or a wrong-case-with-typo value not in the set ('enn-us'). Note 'en' and 'zh' alone are NOT accepted — only the listed tags.

Common situations: Using a bare language code ('en') instead of the required regional form ('en-us'); users in regions with variants not in the allowlist (fr-CA, es-MX); default browser locale 'en' passed straight through; newer locale tags unsupported by this allowlist.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/13d211349b995d4c. Report an issue: GitHub.