jackwener/OpenCLI · error · ArgumentError

Currency must be a three-letter ISO currency code: ${currenc

Error message

Currency must be a three-letter ISO currency code: ${currency}

What it means

parseCurrency upper-cases the currency option (default 'CNY') and requires exactly three ASCII letters A-Z. Any other value — longer codes, digits, symbols, non-Latin scripts, or empty after trimming — throws this ArgumentError.

Source

Thrown at clis/mercury/utils.js:60

    }
    if (!stat || !stat.isFile()) {
        throw new ArgumentError(`Receipt file does not exist: ${receipt}`);
    }
    return receipt;
}

function parseAmount(kwargs) {
    const amount = requireString(kwargs, 'amount').replace(/,/g, '');
    if (!/^\d+(\.\d{1,2})?$/.test(amount) || Number(amount) <= 0) {
        throw new ArgumentError(`Amount must be a positive number with up to two decimals: ${amount}`);
    }
    return amount;
}

function parseCurrency(kwargs) {
    const currency = optionalString(kwargs, 'currency', 'CNY').toUpperCase();
    if (!/^[A-Z]{3}$/.test(currency)) {
        throw new ArgumentError(`Currency must be a three-letter ISO currency code: ${currency}`);
    }
    return currency;
}

function parseDate(kwargs) {
    const date = requireString(kwargs, 'date');
    const match = date.match(/^(\d{4})-(\d{2})-(\d{2})$/);
    if (!match) {
        throw new ArgumentError(`Date must be YYYY-MM-DD: ${date}`);
    }
    const year = Number(match[1]);
    const month = Number(match[2]);
    const day = Number(match[3]);
    const parsed = new Date(Date.UTC(year, month - 1, day));
    if (parsed.getUTCFullYear() !== year || parsed.getUTCMonth() !== month - 1 || parsed.getUTCDate() !== day) {
        throw new ArgumentError(`Date must be a real calendar date: ${date}`);
    }
    return date;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use the ISO 4217 alphabetic code: CNY, USD, EUR, JPY, etc.
  2. Remove symbols, spaces, and punctuation from the value.
  3. Omit --currency entirely if the default CNY is what you want.
  4. Validate input upstream with /^[A-Za-z]{3}$/ before invoking.

Example fix

// before
--currency "USDT"
// after
--currency "USD"
Defensive patterns

Strategy: validation

Validate before calling

function isValidCurrency(c) {
  return typeof c === 'string' && /^[A-Za-z]{3}$/.test(c);
}

Try / catch

try {
  await reimburse({ currency });
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('three-letter ISO currency code')) {
    console.error(`'${currency}' is not ISO 4217; use codes like CNY, USD, EUR`);
  } else throw e;
}

Prevention

When it happens

Trigger: --currency 'us-dollars', 'USDT', '¥', 'CN Y', 'cny ' with a non-strippable char, or any string whose upper-case form is not exactly three A-Z letters.

Common situations: Passing crypto tickers (USDT) instead of ISO 4217 codes; including the currency symbol; locale-full names like 'yuan' or 'RMB' (note 'RMB' is 3 letters and would pass — but 'renminbi' would not); typos like 'CNY+'.

Related errors


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