jackwener/OpenCLI · error · ArgumentError

Unknown 12306 station "${trimmed}"

Error message

Unknown 12306 station "${trimmed}"

What it means

resolveStation() exhausted all lookup strategies — exact code, exact Chinese name, pinyin, and abbreviation — and could not match the input to any station in the bundle. Thrown as ArgumentError with a hint suggesting the accepted input formats (Chinese name, 3-4 letter telecode, or full pinyin).

Source

Thrown at clis/12306/utils.js:89

 * (`shanghaihongqiao`), short alias (`shh`), or city name with a
 * preference for the city's main station.
 */
export function resolveStation(stations, input) {
    const trimmed = String(input ?? '').trim();
    if (!trimmed) throw new ArgumentError('station must not be empty');
    if (STATION_CODE_RE.test(trimmed)) {
        const exact = stations.find((s) => s.code === trimmed);
        if (exact) return exact;
        throw new ArgumentError(`Unknown 12306 station telecode "${trimmed}"`);
    }
    const lower = trimmed.toLowerCase();
    const exactName = stations.find((s) => s.name === trimmed);
    if (exactName) return exactName;
    const exactPinyin = stations.find((s) => s.pinyin === lower);
    if (exactPinyin) return exactPinyin;
    const exactAbbr = stations.find((s) => s.abbr === lower || s.short === lower);
    if (exactAbbr) return exactAbbr;
    throw new ArgumentError(`Unknown 12306 station "${trimmed}"`, 'Try the Chinese name (上海虹桥), the 3-4 letter telecode (AOH), or full pinyin (shanghaihongqiao).');
}

export function validateDate(value) {
    if (!DATE_RE.test(String(value ?? ''))) {
        throw new ArgumentError(`date must be YYYY-MM-DD, got "${value}"`);
    }
    const [y, m, d] = value.split('-').map(Number);
    const date = new Date(Date.UTC(y, m - 1, d));
    if (date.getUTCFullYear() !== y || date.getUTCMonth() !== m - 1 || date.getUTCDate() !== d) {
        throw new ArgumentError(`date "${value}" is not a real calendar date`);
    }
    return value;
}

export function normalizeLimit(value, defaultValue, max) {
    if (value === undefined || value === null || value === '') return defaultValue;
    const n = Number(value);
    if (!Number.isInteger(n) || n < 1) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use the exact Chinese station name, e.g. '上海虹桥'
  2. Use the official 3-4 letter telecode, e.g. 'AOH'
  3. Use the station's full pinyin without spaces, e.g. 'shanghaihongqiao'
  4. Inspect the station bundle list to find the exact name/pinyin/abbr string the library expects

Example fix

// before
const stn = await toStation(ctx, 'shanghai hongqiao');
// after
const stn = await toStation(ctx, 'shanghaihongqiao'); // no spaces
Defensive patterns

Strategy: validation

Validate before calling

function isKnownStation(input, stations) {
  const t = String(input ?? '').trim();
  const l = t.toLowerCase();
  return stations.some((s) => s.code === t || s.name === t || s.pinyin === l || s.abbr === l || s.short === l);
}
if (!isKnownStation('上海虹桥', stations)) throw new Error('unknown station');

Try / catch

try {
  const stn = resolveStation(stations, input);
} catch (e) {
  if (e instanceof ArgumentError && e.hint) {
    console.error(`${e.message}\nHint: ${e.hint}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling fromStation()/toStation() with a value that matches no station by name, pinyin, abbr, short, or code: misspelled names, partial names ('上海' works only if exact), partial pinyin ('shanghongqiao'), or non-station strings like 'Beijing'.

Common situations: Users typing English station names, partial pinyin abbreviations that don't match the abbr/short fields, or extra whitespace/characters around the name.

Related errors


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