jackwener/OpenCLI · error · ArgumentError

--${name} is required (e.g. 北京 / 上海)

Error message

--${name} is required (e.g. 北京 / 上海)

What it means

parsePlaceName validates Chinese place keywords (station, city, port, destination) used to build Ctrip train list query URLs. undefined, null, or blank-after-trim input is rejected with ArgumentError '--<name> is required (e.g. 北京 / 上海)'. These list pages key on the raw Chinese place name, so it must be supplied.

Source

Thrown at clis/ctrip/utils.js:518

          } else {
            plateauRounds = 0;
            lastCount = newCount;
          }
        }
        return countItems();
      })()
    `;
}

/** Validate a 1-50 result limit shared by the browser-mode list commands (default 20). */
export function parseListLimit(raw, fallback = 20) {
    return parseStrictIntegerRange('limit', raw, fallback);
}

/** Validate a Chinese place keyword (station, city, port, or destination) for the browser list queries. */
export function parsePlaceName(name, raw) {
    if (raw === undefined || raw === null || String(raw).trim() === '') {
        throw new ArgumentError(`--${name} is required (e.g. 北京 / 上海)`);
    }
    const value = String(raw).trim();
    // These list pages key on the raw Chinese place name; reject control
    // characters and over-long input rather than passing them through.
    if (value.length > 20 || /[\x00-\x1f]/.test(value)) {
        throw new ArgumentError(`--${name} is not a valid place name: ${JSON.stringify(raw)}`);
    }
    return value;
}

export function buildTrainListUrl(fromName, toName, date) {
    const params = new URLSearchParams({
        dStationName: fromName,
        aStationName: toName,
        dDate: date,
        ticketType: '1',
    });
    return `https://trains.ctrip.com/webapp/train/list?${params.toString()}`;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Provide the Chinese place name, e.g. --from-city 北京 --to-city 上海.
  2. Ensure the flag is present and not an empty shell variable expansion.
  3. Use the same name form the Ctrip list pages accept (raw Chinese keyword); convert pinyin/English names to Chinese first.

Example fix

// before
ctrip trains --from-city "Shanghai" --to-city 北京
// after
ctrip trains --from-city 上海 --to-city 北京
Defensive patterns

Strategy: validation

Validate before calling

if (fromCity === undefined || fromCity === null || String(fromCity).trim() === '') {
  throw new Error('--from-city is required (e.g. 北京 / 上海)');
}

Type guard

const isNonEmptyString = (v) => typeof v === 'string' && v.trim().length > 0;

Try / catch

try {
  const name = parsePlaceName('from-city', raw);
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('is required')) {
    console.error('Usage: --from-city 北京 --to-city 上海');
  } else throw e;
}

Prevention

When it happens

Trigger: Omitting --from-city/--to-city/--port/--destination (or --from-name/--to-name) on train list commands, or passing empty strings/whitespace-only values.

Common situations: Users pass an English/pinyin name ('Shanghai' or 'shanghai') thinking it is optional validation, or forget one leg of a from/to pair; unset shell variables expanding to empty also trigger 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


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