jackwener/OpenCLI · error · ArgumentError
--${name} must be a numeric Trip.com city id, got ${JSON.str
Error message
--${name} must be a numeric Trip.com city id, got ${JSON.stringify(raw)} What it means
parseCityId throws this when a value was provided but is not entirely digits (/^\d+$/ fails). Trip.com city ids are pure numeric strings; names, IATA codes, or ids with letters/punctuation are rejected.
Source
Thrown at clis/trip/utils.js:248
};
const found = detect();
if (found) return resolve(found);
const observer = new MutationObserver(() => {
const result = detect();
if (result) { observer.disconnect(); resolve(result); }
});
observer.observe(document.documentElement, { childList: true, subtree: true });
setTimeout(() => { observer.disconnect(); resolve('timeout'); }, 12000);
})
`;
export function parseCityId(name, raw) {
if (raw === undefined || raw === null || String(raw).trim() === '') {
throw new ArgumentError(`--${name} is required (numeric Trip.com city id, e.g. 338 for London)`);
}
const value = String(raw).trim();
if (!/^\d+$/.test(value)) {
throw new ArgumentError(`--${name} must be a numeric Trip.com city id, got ${JSON.stringify(raw)}`);
}
return value;
}
export function buildHotelSearchUrl(cityId, checkin, checkout) {
const params = new URLSearchParams({
city: cityId,
checkin,
checkout,
locale: 'en_US',
curr: 'USD',
});
return `https://www.trip.com/hotels/list?${params.toString()}`;
}
/**
* Browser-context IIFE that extracts hotel rows from Trip.com's rendered
* `.hotel-card` cards, read by stable class-keyed fieldsView on GitHub (pinned to 49907e53dc)
Solutions
- Use the numeric id only, e.g. --city-id 338
- Convert an IATA code/city name to the Trip.com numeric id via the city search/listing first
- Strip non-digit characters if the id comes embedded in a string ('city:338' -> '338')
- If a number arrives as 338.0 from JSON, use String(Math.trunc(x)) to normalize
Example fix
// before clis-trip hotels --city-id LON --checkin 2026-10-01 --checkout 2026-10-05 // after clis-trip hotels --city-id 338 --checkin 2026-10-01 --checkout 2026-10-05
Defensive patterns
Strategy: validation
Validate before calling
function isNumericId(v) {
return typeof v === 'string' && /^\d+$/.test(v.trim());
}
if (!isNumericId(String(cityId))) throw new Error(`--city-id must be numeric, got ${JSON.stringify(cityId)}`); Type guard
function isNumericCityId(v) {
return /^\d+$/.test(String(v).trim());
} Try / catch
try {
runTripCli(['hotels', '--city-id', cityId]);
} catch (err) {
if (err instanceof ArgumentError && /must be a numeric Trip\.com city id/.test(err.message)) {
console.error(`--city-id must be digits only (e.g. 338), got: ${err.message}`);
process.exitCode = 2;
} else throw err;
} Prevention
- Convert IATA codes or city names to numeric Trip.com ids before calling
- Normalize ids coming from APIs (Math.trunc to drop '.0')
- Strip label prefixes when copy-pasting ids
- Validate with /^\d+$/ at the boundary
When it happens
Trigger: Passing --city-id LON, --city-id 'city:338', --city-id 338.0, --city-id '338 ', handled by trim, so this fires on things like 'ID338', 'London', negative numbers '-338', or decimal '338.5'.
Common situations: Confusing IATA codes with Trip.com numeric ids; copy-pasting an id with a label prefix; receiving an id from an API as a float-formatted number ('338.0'); encoding a name where an id is expected.
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
- --from and --to must differ (got ${fromCode})
- <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-
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/732d69776a5e66bc.
Report an issue: GitHub.