jackwener/OpenCLI · warning · ArgumentError

--from and --to must differ (got ${fromCode})

Error message

--from and --to must differ (got ${fromCode})

What it means

A pure client-side ArgumentError raised before any network activity: the `ctrip flight` command requires --from and --to to be different IATA codes, because the oneway results URL (`oneway-<from>-<to>`) is meaningless when both endpoints are the same and Ctrip would not serve a useful list. The message echoes the offending code so you can see which value was reused.

Source

Thrown at clis/ctrip/flight.js:172

    args: [
        { name: 'from', required: true, positional: true, help: 'Departure IATA code (e.g. BJS / PEK)' },
        { name: 'to', required: true, positional: true, help: 'Arrival IATA code (e.g. SHA / PVG)' },
        { name: 'date', required: true, help: 'Departure date (YYYY-MM-DD)' },
        { name: 'limit', default: DEFAULT_LIMIT, help: `Number of flights (${MIN_LIMIT}-${MAX_LIMIT})` },
    ],
    columns: [
        'rank',
        'airline', 'flightNo', 'aircraft',
        'departureTime', 'departureAirport',
        'arrivalTime', 'arrivalAirport', 'terminal',
        'price', 'currency', 'cabin',
        'url',
    ],
    func: async (page, kwargs) => {
        const fromCode = parseIataCode('from', kwargs.from);
        const toCode = parseIataCode('to', kwargs.to);
        if (fromCode === toCode) {
            throw new ArgumentError(`--from and --to must differ (got ${fromCode})`);
        }
        const date = parseIsoDate('date', kwargs.date);
        const limit = parseFlightLimit(kwargs.limit);

        const searchUrl =
            `https://flights.ctrip.com/online/list/oneway-${fromCode.toLowerCase()}-${toCode.toLowerCase()}` +
            `?depdate=${date}&cabin=Y_S_C_F&adult=1&child=0&infant=0`;
        if (typeof page?.startNetworkCapture !== 'function' ||
            typeof page?.readNetworkCapture !== 'function' ||
            !await page.startNetworkCapture(CAPTURE_PATTERN)) {
            throw new CommandExecutionError('Ctrip flight requires browser response interception');
        }
        await page.readNetworkCapture();
        await page.goto(searchUrl);
        // The initial document can finish before the large batchSearch body.
        // The first rendered card is only a readiness signal; row data still
        // comes exclusively from the structured response below.
        const readiness = await page.evaluate(WAIT_FOR_BATCH_CAPTURE_JS);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass two distinct IATA codes, e.g. `ctrip flight BJS SHA --date 2026-09-01`.
  2. If building routes in a script, filter out pairs where from === to before invoking the command.
  3. If you actually need flights departing from one airport and returning, use the sibling `flight-round` (round-trip) command instead of oneway.

Example fix

// before
await cliRun(['flight', 'PEK', 'PEK', '--date', '2026-09-01']);

// after: guard before calling
if (from === to) throw new Error('from and to must differ');
await cliRun(['flight', from, to, '--date', '2026-09-01']);
Defensive patterns

Strategy: validation

Validate before calling

function validateRoute(from, to) {
  if (String(from).toUpperCase() === String(to).toUpperCase()) {
    throw new Error(`route endpoints must differ (got ${from})`);
  }
}
validateRoute(from, to);

Try / catch

try {
  const rows = await ctripFlight({ from, to, date });
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('must differ')) {
    console.error(`Bad route: ${e.message}`); process.exitCode = 2; return [];
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `ctrip flight BJS BJS --date ...` (or any identical from/to IATA codes, e.g. `PEK PEK`). The check compares parseIataCode('from') === parseIataCode('to') in the command's func at clis/ctrip/flight.js:171.

Common situations: Scripting a loop over routes where a placeholder variable was never replaced; typo where both positional args got the same city; generating routes programmatically and including self-routes by accident; testing the CLI with the same value twice to 'just see it run'.

Related errors


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