jackwener/OpenCLI · error · ArgumentError
--${name} must be a 3-letter IATA code, got ${JSON.stringify
Error message
--${name} must be a 3-letter IATA code, got ${JSON.stringify(raw)} What it means
parseIataCode validates a CLI argument as a 3-letter IATA airport/city code (e.g. LON, NYC). This error is thrown when the value is provided but is not exactly three uppercase ASCII letters after trimming and uppercasing. It is an ArgumentError meant to give the CLI user immediate, actionable feedback.
Source
Thrown at clis/trip/utils.js:23
* results client-side, so the browser-mode commands read the rendered DOM.
* Flight rows are `.result-item` cards keyed by stable `data-testid` anchors
* (`flights-name`, `stopInfoText`, `flight_price_*`).
*/
import { ArgumentError, CommandExecutionError } from '@jackwener/opencli/errors';
const MIN_LIMIT = 1;
const MAX_LIMIT = 50;
const ISO_DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
const POI_SEARCH_ENDPOINT = 'https://www.trip.com/restapi/soa2/14427/poiSearch';
const PACKAGE_SEARCH_ENDPOINT = 'https://www.trip.com/restapi/soa2/19866/FlightSelectSearch';
export function parseIataCode(name, raw) {
if (raw === undefined || raw === null || raw === '') {
throw new ArgumentError(`--${name} is required (3-letter IATA code, e.g. LON, NYC)`);
}
const value = String(raw).trim().toUpperCase();
if (!/^[A-Z]{3}$/.test(value)) {
throw new ArgumentError(`--${name} must be a 3-letter IATA code, got ${JSON.stringify(raw)}`);
}
return value;
}
export function parseIsoDate(name, raw) {
if (raw === undefined || raw === null || raw === '') {
throw new ArgumentError(`--${name} is required (YYYY-MM-DD)`);
}
const value = String(raw).trim();
const m = ISO_DATE_RE.exec(value);
if (!m) {
throw new ArgumentError(`--${name} must be YYYY-MM-DD, got ${JSON.stringify(raw)}`);
}
const year = Number(m[1]);
const month = Number(m[2]);
const day = Number(m[3]);
if (month < 1 || month > 12 || day < 1 || day > 31) {
throw new ArgumentError(`--${name} has invalid month/day: ${value}`);View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a valid 3-letter IATA code, e.g. --from LON --to NYC
- If passing a city name, map it to its IATA code first (via airport lookup/search tooling)
- Quote shell arguments so spaces don't split them, and ensure no trailing whitespace or stray characters
- Check that the variable you interpolate actually contains the code, not an empty string, number, or object
Example fix
// before clis-trip flights --from London --to NYC // after clis-trip flights --from LON --to NYC
Defensive patterns
Strategy: validation
Validate before calling
function isValidIata(v) {
return typeof v === 'string' && /^[A-Z]{3}$/.test(v.trim().toUpperCase());
}
if (!isValidIata(from)) throw new Error(`--from must be a 3-letter IATA code, got ${JSON.stringify(from)}`); Type guard
function isIataCode(v) {
return typeof v === 'string' && /^[A-Z]{3}$/.test(v.trim().toUpperCase());
} Try / catch
import { ArgumentError } from 'clis/trip/utils.js';
try {
runTripCli(['flights', '--from', from, '--to', to]);
} catch (err) {
if (err instanceof ArgumentError && /must be a 3-letter IATA code/.test(err.message)) {
console.error(`Bad airport code: ${err.message}. Use codes like LON, NYC.`);
process.exitCode = 2;
} else throw err;
} Prevention
- Normalize input with String(raw).trim().toUpperCase() before passing
- Maintain a lookup table mapping city names to IATA codes and validate against it
- Quote shell arguments to prevent splitting on spaces
- Validate flags in wrapper scripts before invoking the CLI
When it happens
Trigger: Calling fromCode, toCode, or airport (which delegate to parseIataCode) with a value that, after String(raw).trim().toUpperCase(), fails /^[A-Z]{3}$/ — e.g. 'London', 'lo', 'LON ', 'L1A', numeric 123, or arrays/objects.
Common situations: Users type full city names ('London') instead of IATA codes; shell expands a value into multiple tokens ('NYC LON'); a variable is empty or contains a number; copy-pasted code includes trailing punctuation.
Understand the failure class
Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.
Related errors
- <train-no> "${trainNo}" does not look like a 12306 internal
- --from station must not be empty
- --to station must not be empty
- --seat-types must contain only 12306 seat letters/digits (A-
- --from and --to must differ; both resolved to ${fromStation.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1f62df7dcae08acf.
Report an issue: GitHub.