{"record":{"id":"3239622208c69a9e","repo":"BigPizzaV3/CodexPlusPlus","slug":"page-capturescreenshot-returned-no-image-data","errorCode":null,"errorMessage":"Page.captureScreenshot returned no image data","messagePattern":"Page\\.captureScreenshot returned no image data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/bridge.rs","lineNumber":206,"sourceCode":"        .await\n}\n\npub async fn capture_page_screenshot(\n    websocket_url: &str,\n    output_path: &Path,\n) -> anyhow::Result<u64> {\n    let response = send_cdp_command(\n        websocket_url,\n        \"Page.captureScreenshot\",\n        capture_screenshot_params(),\n    )\n    .await?;\n    let encoded = response\n        .get(\"result\")\n        .and_then(|result| result.get(\"data\"))\n        .and_then(Value::as_str)\n        .filter(|data| !data.is_empty())\n        .ok_or_else(|| anyhow::anyhow!(\"Page.captureScreenshot returned no image data\"))?;\n    let bytes = base64::engine::general_purpose::STANDARD\n        .decode(encoded)\n        .context(\"failed to decode screenshot PNG\")?;\n    if !bytes.starts_with(&[137, 80, 78, 71, 13, 10, 26, 10]) {\n        bail!(\"Page.captureScreenshot returned invalid PNG data\");\n    }\n    crate::settings::atomic_write(output_path, &bytes)\n        .with_context(|| format!(\"failed to save screenshot {}\", output_path.display()))?;\n    Ok(bytes.len() as u64)\n}\n\npub async fn run_periodic_evaluations<F>(\n    websocket_url: &str,\n    period: Duration,\n    mut next_expression: F,\n) -> anyhow::Result<()>\nwhere\n    F: FnMut() -> anyhow::Result<Option<String>>,","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/bridge.rs#L188-L224","documentation":"Raised by `capture_page_screenshot` when the CDP `Page.captureScreenshot` response arrives but contains no usable image payload. The code drills into `result.data`, requires it to be a non-empty string, and fails with this message otherwise. It means Chrome acknowledged the command but returned no base64 screenshot data.","triggerScenarios":"Calling `capture_page_screenshot` against a target whose response JSON lacks `result.data`, has `data: null`, or an empty string — e.g. page crashed, target closed mid-capture, or capture parameters (clip/viewport) invalid so Chrome returned an empty result.","commonSituations":"Screenshotting a tab that was just closed or navigated, capturing a crashed renderer (out-of-memory page), or an old/headless Chrome version returning a different response shape.","solutions":["Re-check the target is alive (query /json list) before capturing","Retry the capture; transient navigation races often clear","Verify CDP command parameters (format, clip rect within viewport)","Log the full CDP response when data is missing to distinguish 'no data' from 'wrong shape'"],"exampleFix":"// before\nlet encoded = response.get(\"result\")?.get(\"data\")?.as_str()?...;\n// after\nlet result = response.get(\"result\")\n    .ok_or_else(|| anyhow::anyhow!(\"captureScreenshot: no result: {response:?}\"))?;\nlet encoded = result.get(\"data\").and_then(Value::as_str)\n    .filter(|d| !d.is_empty())\n    .ok_or_else(|| anyhow::anyhow!(\"Page.captureScreenshot returned no image data (result={result:?})\"))?;","handlingStrategy":"retry","validationCode":"// ensure target is alive before capture\nlet targets: Vec<_> = serde_json::from_str(&http_get(format!(\"http://127.0.0.1:{port}/json/list\"))?)?;\nassert!(targets.iter().any(|t| t[\"id\"] == target_id));","typeGuard":null,"tryCatchPattern":"match capture_page_screenshot(...).await {\n    Err(e) if e.to_string().contains(\"no image data\") => {\n        tokio::time::sleep(Duration::from_millis(300)).await;\n        retry_capture(2)\n    }\n    other => other,\n}","preventionTips":["Verify the target still exists before sending Page.captureScreenshot","Use a stable page-load signal (Page.loadEventFired) before capture","Log the raw CDP response when data is missing"],"tags":["cdp","chrome-devtools","screenshot","unexpected-response"],"backgroundTag":"unexpected-response-shape","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}