jackwener/OpenCLI · error · CommandExecutionError

Ctrip flight API returned HTTP ${status || 'unknown'}

Error message

Ctrip flight API returned HTTP ${status || 'unknown'}

What it means

This CommandExecutionError is thrown when the captured batchSearch response returns an HTTP status that is neither 200 nor 401/403 (e.g. 429, 5xx, or an unknown status when responseStatus is missing). It signals the Ctrip API call itself failed at the transport level, so no flight data can be parsed. Status 0/undefined yields 'unknown', typically meaning the response never completed or the capture metadata was lost.

Source

Thrown at clis/ctrip/flight.js:72

    return codes.length > 0 ? codes.map((code) => labels[code]).join('/') : (cleanString(value) || null);
}

function parseBatchSearchCaptures(entries) {
    if (!Array.isArray(entries)) {
        throw new CommandExecutionError('Ctrip flight network capture returned malformed entries');
    }
    const captured = entries.filter((entry) => String(entry?.url || '').includes(CAPTURE_PATTERN));
    if (captured.length === 0) return null;

    const byId = new Map();
    let finished = false;
    for (const entry of captured) {
        const status = Number(entry?.responseStatus || 0);
        if (status === 401 || status === 403) {
            throw new AuthRequiredError('flights.ctrip.com', `Ctrip flight API returned HTTP ${status}; complete any verification in the browser and retry`);
        }
        if (status !== 200) {
            throw new CommandExecutionError(`Ctrip flight API returned HTTP ${status || 'unknown'}`);
        }
        if (entry?.responseBodyTruncated === true) {
            throw new CommandExecutionError('Ctrip flight API response exceeded the browser capture limit');
        }
        if (typeof entry?.responsePreview !== 'string') {
            throw new CommandExecutionError('Ctrip flight API response body was unavailable');
        }
        let payload;
        try {
            payload = JSON.parse(entry.responsePreview);
        }
        catch {
            throw new CommandExecutionError('Ctrip flight API returned invalid JSON');
        }
        if (payload?.status !== 0) {
            throw new CommandExecutionError(`Ctrip flight API failed (status=${String(payload?.status)}): ${cleanString(payload?.msg) || 'unknown error'}`);
        }
        const itineraries = payload?.data?.flightItineraryList;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the search after a short backoff — 429 and 5xx are usually transient.
  2. Check the reported status code: 429 means back off and slow the request rate; 5xx means wait for Ctrip to recover.
  3. If status is 'unknown', keep the browser open and ensure the page stays on the results flow until the batchSearch response is captured.
  4. Verify network/proxy stability between the automation browser and flights.ctrip.com.

Example fix

// before: immediate retry
const rows = await cli.itineraries(args);
// after: backoff on transient HTTP failures
try {
  const rows = await cli.itineraries(args);
} catch (err) {
  if (err instanceof CommandExecutionError && /HTTP (429|5\d\d)/.test(err.message)) {
    await sleep(30_000);
    return cli.itineraries(args);
  }
  throw err;
}
Defensive patterns

Strategy: retry

Try / catch

try {
  return await cli.itineraries(args);
} catch (err) {
  const m = /HTTP (\d+|'unknown')/.exec(err.message || '');
  const status = m && m[1] !== 'unknown' ? Number(m[1]) : 0;
  if (status === 429 || status >= 500) {
    await sleep(backoffMs);
    return cli.itineraries(args); // bounded retries
  }
  throw err;
}

Prevention

When it happens

Trigger: Captured /international/search/api/search/batchSearch entry whose responseStatus is e.g. 429 (rate limited), 500/502/503 (Ctrip server error), or 0/missing (request aborted, navigation interrupted, or capture failed to record status).

Common situations: Hammering the CLI with repeated searches leading to 429 rate limiting; transient Ctrip server incidents (5xx); closing the browser or navigating away before the response completes (status unknown); CDP capture failing mid-request.

Related errors


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