jackwener/OpenCLI · error · ArgumentError
'${rawInput}' does not look like a guazi clue id (a number,
Error message
'${rawInput}' does not look like a guazi clue id (a number, or a /car-detail/c<id>.html URL) What it means
normalizeClueId extracts the numeric id via /car-detail\/(\d+)/ or ^c?(\d+)$; if neither matches it throws this ArgumentError echoing the raw input. It fires when the value is non-empty but not shaped like a Guazi clue id.
Source
Thrown at clis/guazi/utils.js:75
/** Resolve a city arg (name or code) to a Guazi city code; defaults to bj. */
export function resolveCityCode(cityArg) {
if (cityArg == null || cityArg === '') return 'bj';
const raw = String(cityArg).trim().toLowerCase();
if (CITY_CODE[raw]) return CITY_CODE[raw];
if (CITY_CODE[String(cityArg).trim()]) return CITY_CODE[String(cityArg).trim()];
if (/^[a-z]{2,3}$/.test(raw)) return raw; // already a code
const names = Object.keys(CITY_CODE).filter((k) => /^[a-z]+$/.test(k)).join(', ');
throw new ArgumentError('city', `unknown city '${cityArg}'. pass a Guazi city code or one of: ${names}`);
}
/** Normalize a clue id: a bare number or a /car-detail/c<id>.htm(l) URL. */
export function normalizeClueId(rawInput) {
const raw = String(rawInput || '').trim();
if (!raw) throw new ArgumentError('clue_id must be a non-empty value');
const m = raw.match(/car-detail\/c(\d+)/) || raw.match(/^c?(\d+)$/);
if (!m) {
throw new ArgumentError(`'${rawInput}' does not look like a guazi clue id (a number, or a /car-detail/c<id>.html URL)`);
}
return m[1];
}
export function requireLimit(value, def, max) {
const raw = value == null || value === '' ? def : value;
const n = typeof raw === 'number' ? raw : Number(String(raw).trim());
if (!Number.isInteger(n) || n < 1 || n > max) {
throw new ArgumentError(`limit must be an integer between 1 and ${max}`);
}
return n;
}
export function clean(s) {
return String(s == null ? '' : s).replace(/\s+/g, ' ').trim();
}
export function requireText(value, label) {View on GitHub (pinned to 49907e53dc)
Solutions
- Pass just the numeric id, e.g. 100200300, or the 'c'-prefixed form c100200300.
- If passing a URL, make sure it contains /car-detail/c<digits> — strip query strings and extra path segments if needed.
- Trim quotes/whitespace and remove any label text before invoking.
- Extract the digits programmatically: (input.match(/(\d+)/) || [])[1].
Example fix
// before guazi car --clue_id "car 100200300" // after guazi car --clue_id 100200300
Defensive patterns
Strategy: validation
Validate before calling
function isClueId(v) {
const s = String(v ?? '').trim();
return /car-detail\/c(\d+)/.test(s) || /^c?\d+$/.test(s);
}
if (!isClueId(input)) throw new Error(`not a clue id: ${input}`); Type guard
function isClueId(v): v is string {
return typeof v === 'string' &&
(/car-detail\/c\d+/.test(v) || /^c?\d+$/.test(v.trim()));
} Try / catch
try {
const car = await guaziCar({ clue_id: raw });
} catch (e) {
if (/does not look like a guazi clue id/.test(e.message)) {
const m = String(raw).match(/(\d+)/);
if (m) return guaziCar({ clue_id: m[1] });
}
throw e;
} Prevention
- Extract just the digits before passing ids
- Strip labels, quotes, and query strings from copied values
- Validate with the same regexes the library uses
- Keep ids in dedicated fields, not free-text lines
When it happens
Trigger: Passing 'car 100200300', 'https://m.guazi.com/car/100200300x.html' (non-digits in id), a full detail URL with a slug like '/car-detail/c100200300-bmw.html' (trailing slug breaks ^c?\d+$ and the URL regex still matches though), or an alphanumeric SKU like 'abc123'.
Common situations: Copying a title line instead of the id from browse output; pasting a URL from a different site section (/buy/, /qiugou/); including surrounding text or quotes around the id in a script.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — 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/b70ae1065ce14304.
Report an issue: GitHub.