{"record":{"id":"5ad6f873e4ce8fdf","repo":"RightNow-AI/openfang","slug":"screenshot-failed-e","errorCode":null,"errorMessage":"Screenshot failed: {e}","messagePattern":"Screenshot failed: (.+?)","errorType":"error_code","errorClass":"BrowserResponse","httpStatus":null,"severity":"error","filePath":"crates/openfang-runtime/src/browser.rs","lineNumber":538,"sourceCode":"                \"Page.captureScreenshot\",\n                serde_json::json!({ \"format\": \"png\" }),\n            )\n            .await\n        {\n            Ok(result) => {\n                let b64 = result[\"data\"].as_str().unwrap_or(\"\");\n                let url = self\n                    .cdp\n                    .run_js(\"location.href\")\n                    .await\n                    .ok()\n                    .and_then(|v| v.as_str().map(String::from))\n                    .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 {","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/RightNow-AI/openfang/blob/acf2587e46be174c10200489c9a2d23a39a98aeb/crates/openfang-runtime/src/browser.rs#L520-L556","documentation":"This error fires when the CDP command \"Page.captureScreenshot\" fails during cmd_screenshot, meaning the headless browser could not capture a PNG of the current page. The CDP send returns an Err when the browser target is unavailable or has crashed, the page or tab was closed or navigated mid-request, DevTools protocol communication broke, or the browser refused the screenshot request; the underlying CDP error is embedded in the message. It indicates the screenshot operation itself failed at the protocol level, not that the resulting image data was empty or malformed (a missing \"data\" field would silently yield an empty base64 string instead).","triggerScenarios":"self.cdp Page.captureScreenshot (via run/send) resolves to Err: browser disconnected, target crashed, or CDP rejected the capture (e.g. unsupported surface, tab closing).","commonSituations":"Capturing during a navigation or while the tab is being closed; headless Chrome crashed; very large viewport causing the capture to fail/timeout.","solutions":["Read the interpolated {e} for the CDP-level cause.","Retry the screenshot after wait_for_load completes — avoid capturing mid-navigation.","Reconnect/restart the browser session if the connection dropped.","Reduce viewport size or use format options if the capture times out on huge pages."],"exampleFix":"// before\nlet shot = browser.execute(\"screenshot\", \"\").await?;\n// after\nbrowser.wait_for_load().await?;\nlet shot = match browser.execute(\"screenshot\", \"\").await {\n    Ok(s) => s,\n    Err(_) => {\n        tokio::time::sleep(std::time::Duration::from_millis(300)).await;\n        browser.execute(\"screenshot\", \"\").await?\n    }\n};","handlingStrategy":"retry","validationCode":"// Only screenshot a settled page:\nbrowser.wait_for_load().await?;\nif !browser.is_connected().await { browser.reconnect().await?; }","typeGuard":"fn screenshot_payload_valid(resp: &BrowserResponse) -> bool {\n    resp.success && resp.value.get(\"image_base64\").and_then(|v| v.as_str()).map_or(false, |s| !s.is_empty())\n}","tryCatchPattern":"// Rust\nlet shot = match browser.execute(\"screenshot\", \"\").await {\n    Ok(s) if s.success => Ok(s),\n    Ok(s) => Err(anyhow!(s.error)),\n    Err(_) => {\n        tokio::time::sleep(Duration::from_millis(300)).await;\n        browser.execute(\"screenshot\", \"\").await.map_err(Into::into)\n    }\n};","preventionTips":["Never screenshot during navigation; wait for load first.","Keep the viewport at a sane size to avoid capture timeouts.","Verify the base64 payload decodes before persisting it.","Retry once on transport errors before failing the workflow."],"tags":["cdp","screenshot","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"}