jackwener/OpenCLI · error · ArgumentError
--city is required (numeric city ID from `ctrip search` or `
Error message
--city is required (numeric city ID from `ctrip search` or `ctrip hotel-suggest`)
What it means
parseCityId requires the --city flag to be present and non-blank: undefined, null, empty or whitespace-only strings are rejected. The value must be a numeric Ctrip city ID (a positive integer obtained from `ctrip search` or `ctrip hotel-suggest`). It throws ArgumentError immediately so the caller knows to supply an ID rather than a city name.
Source
Thrown at clis/ctrip/utils.js:251
* Ctrip URL accepts both single-airport (PEK / PVG) and metro-group (BJS / SHA) codes.
*/
export function parseIataCode(name, raw) {
if (raw === undefined || raw === null || raw === '') {
throw new ArgumentError(`--${name} is required (3-letter IATA code, e.g. PEK, SHA)`);
}
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;
}
/**
* Validate a numeric Ctrip city ID (returned by `ctrip search` / `ctrip hotel-suggest`).
*/
export function parseCityId(raw) {
if (raw === undefined || raw === null || raw === '' || String(raw).trim() === '') {
throw new ArgumentError('--city is required (numeric city ID from `ctrip search` or `ctrip hotel-suggest`)');
}
try {
return parseStrictPositiveInteger('city', raw);
} catch {
throw new ArgumentError(`--city must be a positive integer city ID, got ${JSON.stringify(raw)}`);
}
}
/**
* Pick the best lat/lon from a Ctrip hotel `positionInfo.mapCoordinate` array.
*
* Each entry has a `coordinateType` (1=WGS84, 2=GCJ02, 3=BD09 / Baidu). We prefer
* WGS84 when present (most portable), then fall through. All coordinates are
* strings in the API, so we Number() and reject NaN.
*/
export function pickHotelMapCoords(mapCoordinate) {
if (!Array.isArray(mapCoordinate) || mapCoordinate.length === 0) {
return { lat: null, lon: null };View on GitHub (pinned to 49907e53dc)
Solutions
- Run `ctrip search <name>` or `ctrip hotel-suggest` first and pass the returned numeric city ID to --city.
- Make sure --city is actually set and not an empty shell variable.
- Do not pass a Chinese city name; only numeric IDs are accepted (names go through other flags like parsePlaceName).
Example fix
// before
ctrip hotels --city "上海"
// after
const id = await ctripSearchCityId('上海'); // e.g. 1
ctrip hotels --city 1 Defensive patterns
Strategy: validation
Validate before calling
if (cityId === undefined || cityId === null || String(cityId).trim() === '') {
throw new Error('--city is required: run `ctrip search` to get a numeric city ID');
} Type guard
const isPresent = (v) => v !== undefined && v !== null && String(v).trim() !== '';
Try / catch
try {
const id = parseCityId(raw);
} catch (e) {
if (e instanceof ArgumentError && e.message.includes('--city is required')) {
console.error('Provide --city <numericId> from `ctrip search`.');
} else throw e;
} Prevention
- Always run `ctrip search` / `ctrip hotel-suggest` first and store the numeric ID.
- Check shell variables are non-empty before interpolating into flags (${VAR:?} in bash).
- Never pass city names to --city; names belong to the search step.
When it happens
Trigger: Running a ctrip hotel command with --city omitted entirely, or with --city "" / --city " " (empty or whitespace after shell expansion).
Common situations: Users pass a city NAME like '上海' to --city instead of the numeric ID, or an unset environment variable expands to empty. IDs must come from `ctrip search` / `ctrip hotel-suggest`, so skipping that lookup step triggers this.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- symbol is required
- Either --product-id or --url is required
- --${name} is required (e.g. 北京 / 上海)
- hotel id is required (numeric id from `ctrip hotel-suggest`,
- must be a conversation id, /app/<id> URL, or sidebar title
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b413660494642ca8.
Report an issue: GitHub.