jackwener/OpenCLI · error · Error

Network capture is unavailable, so --wait-until networkidle

Error message

Network capture is unavailable, so --wait-until networkidle cannot be satisfied

What it means

When --wait-until networkidle is requested, clis/web/read.js relies on network capture (request/response interception) to detect when the network has gone quiet. If the active browser/page backend does not support capturing network traffic, the command cannot ever determine idle state, so it fails fast with this error instead of hanging.

Source

Thrown at clis/web/read.js:439

        const captureSupported = (waitUntil === 'networkidle' || shouldDiagnose)
            ? await maybeStartNetworkCapture(page)
            : false;
        // Navigate to the target URL
        await page.goto(url);
        if (kwargs['wait-for']) {
            const waitResult = await page.evaluate(buildWaitForSelectorAcrossFramesJs(String(kwargs['wait-for']), waitSeconds * 1000));
            if (waitResult?.invalidSelector) {
                throw new Error(`Invalid --wait-for selector "${kwargs['wait-for']}": ${waitResult.error || 'querySelector failed'}`);
            }
            if (!waitResult?.ok) {
                throw new Error(`Timed out waiting for selector "${kwargs['wait-for']}" in main document or same-origin iframes`);
            }
        } else if (waitUntil !== 'networkidle') {
            await page.wait(waitSeconds);
        }
        if (waitUntil === 'networkidle') {
            if (!captureSupported) {
                throw new Error('Network capture is unavailable, so --wait-until networkidle cannot be satisfied');
            }
            const idle = await waitForNetworkIdle(page, waitSeconds, networkEntries);
            if (!idle?.ok) {
                throw new Error(`Timed out waiting for network idle after ${waitSeconds}s`);
            }
        }
        // Extract article content using browser-side heuristics
        const data = await page.evaluate(buildRenderAwareExtractorJs({ frames: frameMode }));
        if (captureSupported) await drainNetworkCapture(page, networkEntries);
        if (shouldDiagnose) process.stderr.write(formatDiagnostics(data, networkEntries, captureSupported));
        // Determine Referer from URL for image downloads
        let referer = '';
        try {
            const parsed = new URL(url);
            referer = parsed.origin + '/';
        }
        catch { /* ignore */ }
        const result = await downloadArticle({

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use a browser backend that supports network capture (e.g. a CDP-based driver).
  2. Drop --wait-until networkidle and use the default fixed wait: --wait <seconds>.
  3. Use --wait-for <selector> as a deterministic readiness signal instead of network idle.
  4. Check driver/env configuration that disables network interception and re-enable it.

Example fix

// before
web read https://example.com --wait-until networkidle
// after (capture unavailable)
web read https://example.com --wait-until load --wait 5
Defensive patterns

Strategy: fallback

Validate before calling

// Check driver capability before requesting networkidle
if (!driver.supportsNetworkCapture) {
  opts.waitUntil = 'load'; // degrade instead of failing
}

Type guard

function captureSupported(page) { return typeof page.captureNetwork === 'function' || typeof page.networkEntries === 'function'; }

Try / catch

try {
  await readPage(url, { waitUntil: 'networkidle' });
} catch (e) {
  if (String(e.message).includes('Network capture is unavailable')) {
    await readPage(url, { waitUntil: 'load', waitSeconds: 5 });
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking the web read command with --wait-until networkidle against a page/browser object whose driver lacks network interception (captureSupported === false) — e.g. a driver that only exposes basic goto/evaluate, or capture disabled in the environment.

Common situations: Using a lightweight or remote browser backend without CDP/interception support; a driver upgrade/downgrade that dropped network-capture support; running in an environment where interception is unavailable (restricted sandbox).

Related errors


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