jackwener/OpenCLI · error · ArgumentError

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

Error message

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

What it means

An ArgumentError raised by the ctrip flight-round CLI argument validation: the parsed --from and --from IATA codes are identical, which would make a round-trip search nonsensical (Ctrip rejects same-origin round trips). parseIataCode normalizes both values before comparing, so 'PEK' vs 'pek' still matches and throws.

Source

Thrown at clis/ctrip/flight-round.js:69

        { 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: 'depart', required: true, help: 'Outbound date (YYYY-MM-DD)' },
        { name: 'return', required: true, help: 'Return date (YYYY-MM-DD), on or after depart' },
        { name: 'limit', default: 20, help: 'Number of flights (1-50)' },
    ],
    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 depart = parseIsoDate('depart', kwargs.depart);
        const ret = parseIsoDate('return', kwargs.return);
        if (ret < depart) {
            throw new ArgumentError(`--return (${ret}) must be on or after --depart (${depart})`);
        }
        const limit = parseListLimit(kwargs.limit);

        const searchUrl =
            `https://flights.ctrip.com/online/list/round-${fromCode.toLowerCase()}-${toCode.toLowerCase()}` +
            `?depdate=${depart}_${ret}&cabin=Y_S_C_F&adult=1&child=0&infant=0`;
        await page.goto(searchUrl);
        const waitResult = await page.evaluate(WAIT_FOR_FLIGHTS_ROUND_JS);
        if (waitResult === 'captcha') {
            throw new AuthRequiredError('flights.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
        }
        if (waitResult !== 'content') {
            throw new CommandExecutionError(`Ctrip round-trip flight page did not render flight cards (state=${String(waitResult)})`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass distinct origin and destination IATA codes for --from and --to.
  2. If building calls programmatically, validate fromCode !== toCode before invoking the CLI.
  3. Check for swapped or duplicated variables feeding the two flags in your script.

Example fix

// before
run(['flight-round', '--from', origin, '--to', origin, '--depart', d, '--return', r]);
// after
if (origin === destination) throw new Error('origin and destination must differ');
run(['flight-round', '--from', origin, '--to', destination, '--depart', d, '--return', r]);
Defensive patterns

Strategy: validation

Validate before calling

const iata = (s) => String(s || '').trim().toUpperCase();
if (iata(from) === iata(to)) throw new Error('origin and destination IATA codes must differ');

Type guard

function isDistinctRoute(from, to) { return String(from).trim().toUpperCase() !== String(to).trim().toUpperCase(); }

Try / catch

try { await cli(['flight-round', args]); } catch (e) { if (e instanceof ArgumentError) { console.error('usage:', e.message); process.exitCode = 2; } else throw e; }

Prevention

When it happens

Trigger: Calling the flight-round command where kwargs.from and kwargs.to resolve to the same 3-letter IATA code, e.g. `--from PEK --to PEK` or `--from pek --to PEK`.

Common situations: Programmatic loop building routes where origin/destination variables were accidentally set from the same field; default values filled in for both flags; copy-paste mistakes in shell scripts.

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


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