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
- Retry the search after a short backoff — 429 and 5xx are usually transient.
- Check the reported status code: 429 means back off and slow the request rate; 5xx means wait for Ctrip to recover.
- If status is 'unknown', keep the browser open and ensure the page stays on the results flow until the batchSearch response is captured.
- 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
- Add exponential backoff and a retry cap for 429/5xx statuses.
- Space out searches; do not run many routes in rapid succession.
- Keep the browser/tab alive until the CLI completes so responses are not aborted (unknown status).
- Monitor Ctrip status/incidents if 5xx errors cluster.
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
- HTTP ${result.httpStatus} from /api/auth/session
- autohome ${contextHint} HTTP ${resp.status}
- dongchedi ${contextHint} HTTP ${resp.status}
- eastmoney convertible failed: HTTP ${resp.status}
- HTTP_ERROR
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3e7b12391040d15e.
Report an issue: GitHub.