jackwener/OpenCLI · error · CommandExecutionError
Ctrip flight requires browser response interception
Error message
Ctrip flight requires browser response interception
What it means
This CommandExecutionError fires when the browser page object passed to the `ctrip flight` command does not support the network-response interception the command depends on: page.startNetworkCapture and page.readNetworkCapture must both be functions, and startNetworkCapture('/international/search/api/search/batchSearch') must return a truthy value. The command's strategy is Strategy.INTERCEPT — row data comes exclusively from the captured batchSearch XHR, so without interception it cannot produce results.
Source
Thrown at clis/ctrip/flight.js:183
'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);
if (readiness === 'captcha') {
throw new AuthRequiredError('flights.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
}
const itineraries = parseBatchSearchCaptures(await page.readNetworkCapture());
if (!itineraries) {
throw new TimeoutError('Ctrip flight API capture', CAPTURE_TIMEOUT_SECONDS, 'No batchSearch response was observed after opening the results page.');
}
if (itineraries.length === 0) {
throw new EmptyResultError('ctrip flight', `No flights for ${fromCode}→${toCode} on ${date}`);
}
const rows = itinerariesView on GitHub (pinned to 49907e53dc)
Solutions
- Run the command through the standard opencli browser (browser: true, Strategy.INTERCEPT) so page gets startNetworkCapture/readNetworkCapture.
- Upgrade @jackwener/opencli to a version whose browser exposes the network capture APIs.
- If testing, stub page.startNetworkCapture (returning true) and page.readNetworkCapture in your mock page object.
- Check that the CDP session can enable network interception (no restricted browser/extension blocking Fetch/Network domains).
Example fix
// before: plain puppeteer page handed to the command
const page = await browser.newPage();
await runCommand('ctrip flight', { page });
// after: use the opencli-managed page with capture support
const page = await opencliBrowser.newPage({ intercept: true });
await runCommand('ctrip flight', { page }); Defensive patterns
Strategy: type-guard
Validate before calling
// Verify capture support before invoking the command
function supportsInterception(page) {
return typeof page?.startNetworkCapture === 'function' &&
typeof page?.readNetworkCapture === 'function';
}
if (!supportsInterception(page)) throw new Error('page lacks network capture APIs'); Type guard
function isInterceptCapablePage(page) {
return page != null &&
typeof page.startNetworkCapture === 'function' &&
typeof page.readNetworkCapture === 'function' &&
typeof page.goto === 'function' &&
typeof page.evaluate === 'function';
} Try / catch
try {
const rows = await ctripFlight({ from, to, date });
} catch (e) {
if (e instanceof CommandExecutionError && e.message.includes('requires browser response interception')) {
throw new Error('Use the opencli-managed browser (Strategy.INTERCEPT) — the current page object cannot capture network responses.');
}
throw e;
} Prevention
- Always run intercept-strategy commands through the opencli-managed browser.
- In tests, stub startNetworkCapture/readNetworkCapture on mock page objects.
- Upgrade opencli when browser capture APIs change between versions.
- Smoke-test page capabilities (typeof checks) before dispatching commands.
When it happens
Trigger: Running the command against a page object that lacks startNetworkCapture/readNetworkCapture (e.g. a plain browser-automation wrapper instead of the opencli CDP browser), passing a null/undefined page, or startNetworkCapture returning false because the CDP session could not attach a network listener.
Common situations: Invoking the command with a custom or mocked page in tests that only implement goto/evaluate; using an outdated opencli runtime whose browser doesn't expose capture APIs; running in an environment where CDP network domains can't be enabled (restricted browser, incompatible headless shell); a registry misconfiguration overriding the browser/strategy options.
Related errors
- BOSS search requires CDP network capture
- Browser page required
- Browser page required
- Browser page required
- 1688 ${action} navigation lost the current browser target
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b8574d64b94530be.
Report an issue: GitHub.