{"record":{"id":"c3a7347df2d93801","repo":"jackwener/OpenCLI","slug":"network-capture-is-unavailable-so-wait-until-ne","errorCode":null,"errorMessage":"Network capture is unavailable, so --wait-until networkidle cannot be satisfied","messagePattern":"Network capture is unavailable, so --wait-until networkidle cannot be satisfied","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/web/read.js","lineNumber":439,"sourceCode":"        const captureSupported = (waitUntil === 'networkidle' || shouldDiagnose)\n            ? await maybeStartNetworkCapture(page)\n            : false;\n        // Navigate to the target URL\n        await page.goto(url);\n        if (kwargs['wait-for']) {\n            const waitResult = await page.evaluate(buildWaitForSelectorAcrossFramesJs(String(kwargs['wait-for']), waitSeconds * 1000));\n            if (waitResult?.invalidSelector) {\n                throw new Error(`Invalid --wait-for selector \"${kwargs['wait-for']}\": ${waitResult.error || 'querySelector failed'}`);\n            }\n            if (!waitResult?.ok) {\n                throw new Error(`Timed out waiting for selector \"${kwargs['wait-for']}\" in main document or same-origin iframes`);\n            }\n        } else if (waitUntil !== 'networkidle') {\n            await page.wait(waitSeconds);\n        }\n        if (waitUntil === 'networkidle') {\n            if (!captureSupported) {\n                throw new Error('Network capture is unavailable, so --wait-until networkidle cannot be satisfied');\n            }\n            const idle = await waitForNetworkIdle(page, waitSeconds, networkEntries);\n            if (!idle?.ok) {\n                throw new Error(`Timed out waiting for network idle after ${waitSeconds}s`);\n            }\n        }\n        // Extract article content using browser-side heuristics\n        const data = await page.evaluate(buildRenderAwareExtractorJs({ frames: frameMode }));\n        if (captureSupported) await drainNetworkCapture(page, networkEntries);\n        if (shouldDiagnose) process.stderr.write(formatDiagnostics(data, networkEntries, captureSupported));\n        // Determine Referer from URL for image downloads\n        let referer = '';\n        try {\n            const parsed = new URL(url);\n            referer = parsed.origin + '/';\n        }\n        catch { /* ignore */ }\n        const result = await downloadArticle({","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/web/read.js#L421-L457","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Use a browser backend that supports network capture (e.g. a CDP-based driver).","Drop --wait-until networkidle and use the default fixed wait: --wait <seconds>.","Use --wait-for <selector> as a deterministic readiness signal instead of network idle.","Check driver/env configuration that disables network interception and re-enable it."],"exampleFix":"// before\nweb read https://example.com --wait-until networkidle\n// after (capture unavailable)\nweb read https://example.com --wait-until load --wait 5","handlingStrategy":"fallback","validationCode":"// Check driver capability before requesting networkidle\nif (!driver.supportsNetworkCapture) {\n  opts.waitUntil = 'load'; // degrade instead of failing\n}","typeGuard":"function captureSupported(page) { return typeof page.captureNetwork === 'function' || typeof page.networkEntries === 'function'; }","tryCatchPattern":"try {\n  await readPage(url, { waitUntil: 'networkidle' });\n} catch (e) {\n  if (String(e.message).includes('Network capture is unavailable')) {\n    await readPage(url, { waitUntil: 'load', waitSeconds: 5 });\n  } else throw e;\n}","preventionTips":["Confirm your browser backend supports network interception before using networkidle","Feature-check the driver API at startup","Use --wait-for selectors as a portable alternative to networkidle","Pin/verify driver versions in CI environments"],"tags":["browser","network","configuration","unsupported-feature"],"backgroundTag":"capability-not-supported","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}