{"record":{"id":"ddd817f057a41f64","repo":"RightNow-AI/openfang","slug":"readpage-failed-e","errorCode":null,"errorMessage":"ReadPage failed: {e}","messagePattern":"ReadPage failed: (.+?)","errorType":"error_code","errorClass":"BrowserResponse","httpStatus":null,"severity":"error","filePath":"crates/openfang-runtime/src/browser.rs","lineNumber":551,"sourceCode":"                    .unwrap_or_default();\n                BrowserResponse::ok(\n                    serde_json::json!({\"image_base64\": b64, \"url\": url, \"format\": \"png\"}),\n                )\n            }\n            Err(e) => BrowserResponse::err(format!(\"Screenshot failed: {e}\")),\n        }\n    }\n\n    async fn cmd_read_page(&self) -> BrowserResponse {\n        match self.cdp.run_js(EXTRACT_CONTENT_JS).await {\n            Ok(val) => {\n                let parsed: serde_json::Value = val\n                    .as_str()\n                    .and_then(|s| serde_json::from_str(s).ok())\n                    .unwrap_or(val);\n                BrowserResponse::ok(parsed)\n            }\n            Err(e) => BrowserResponse::err(format!(\"ReadPage failed: {e}\")),\n        }\n    }\n\n    async fn cmd_scroll(&self, direction: &str, amount: i32) -> BrowserResponse {\n        let (dx, dy) = match direction {\n            \"up\" => (0, -amount),\n            \"down\" => (0, amount),\n            \"left\" => (-amount, 0),\n            \"right\" => (amount, 0),\n            _ => (0, amount),\n        };\n        let js = format!(\"window.scrollBy({dx}, {dy}); JSON.stringify({{scrollX: window.scrollX, scrollY: window.scrollY}})\");\n        match self.cdp.run_js(&js).await {\n            Ok(val) => {\n                let parsed: serde_json::Value = val\n                    .as_str()\n                    .and_then(|s| serde_json::from_str(s).ok())\n                    .unwrap_or(val);","sourceCodeStart":533,"sourceCodeEnd":569,"githubUrl":"https://github.com/RightNow-AI/openfang/blob/acf2587e46be174c10200489c9a2d23a39a98aeb/crates/openfang-runtime/src/browser.rs#L533-L569","documentation":"cmd_read_page runs EXTRACT_CONTENT_JS through CDP to pull readable page content. On a CDP Err this message wraps the transport error — content extraction never executed, so no page text is available in the response.","triggerScenarios":"self.cdp.run_js(EXTRACT_CONTENT_JS) resolves to Err: browser disconnected, execution context destroyed mid-extraction, or the evaluation failed/timed out on very heavy pages.","commonSituations":"Calling read_page while the page is navigating or crashed; huge single-page apps making the extraction script exceed CDP evaluation limits; headless browser killed by OOM.","solutions":["Read the interpolated {e} for the underlying CDP cause.","Wait for load completion and retry read_page once before surfacing the error.","Reconnect the browser session if the connection dropped.","If extraction times out on heavy pages, narrow extraction (e.g. main/article element) to reduce work."],"exampleFix":"// before\nlet content = browser.execute(\"read_page\", \"\").await?;\n// after\nlet content = match browser.execute(\"read_page\", \"\").await {\n    Ok(c) => c,\n    Err(_) => {\n        browser.wait_for_load().await?;\n        browser.execute(\"read_page\", \"\").await?\n    }\n};","handlingStrategy":"retry","validationCode":"// Ensure the page is loaded and connected before extraction:\nbrowser.wait_for_load().await?;\nif !browser.is_connected().await { browser.reconnect().await?; }","typeGuard":"fn extract_has_content(resp: &BrowserResponse) -> bool {\n    resp.success && match &resp.value {\n        serde_json::Value::Object(m) => !m.is_empty(),\n        serde_json::Value::String(s) => !s.trim().is_empty(),\n        _ => false,\n    }\n}","tryCatchPattern":"// Rust\nlet content = match browser.execute(\"read_page\", \"\").await {\n    Ok(c) if c.success => Ok(c),\n    Ok(c) => Err(anyhow!(c.error)),\n    Err(_) => {\n        browser.wait_for_load().await?;\n        browser.execute(\"read_page\", \"\").await.map_err(Into::into)\n    }\n};","preventionTips":["Only extract after wait_for_load; never mid-navigation.","Watch for OOM on very heavy pages; scope extraction to main content.","Reconnect on transport errors before retrying extraction.","Cache extracted content briefly to reduce repeated heavy evaluations."],"tags":["cdp","content-extraction","browser-automation"],"backgroundTag":"cdp-command-failed","analyzedSha":"acf2587e46be174c10200489c9a2d23a39a98aeb","analyzedAt":"2026-09-02T22:42:28.464Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}