RightNow-AI/openfang · error · BrowserResponse

Screenshot failed: {e}

Error message

Screenshot failed: {e}

What it means

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).

Source

Thrown at crates/openfang-runtime/src/browser.rs:538

                "Page.captureScreenshot",
                serde_json::json!({ "format": "png" }),
            )
            .await
        {
            Ok(result) => {
                let b64 = result["data"].as_str().unwrap_or("");
                let url = self
                    .cdp
                    .run_js("location.href")
                    .await
                    .ok()
                    .and_then(|v| v.as_str().map(String::from))
                    .unwrap_or_default();
                BrowserResponse::ok(
                    serde_json::json!({"image_base64": b64, "url": url, "format": "png"}),
                )
            }
            Err(e) => BrowserResponse::err(format!("Screenshot failed: {e}")),
        }
    }

    async fn cmd_read_page(&self) -> BrowserResponse {
        match self.cdp.run_js(EXTRACT_CONTENT_JS).await {
            Ok(val) => {
                let parsed: serde_json::Value = val
                    .as_str()
                    .and_then(|s| serde_json::from_str(s).ok())
                    .unwrap_or(val);
                BrowserResponse::ok(parsed)
            }
            Err(e) => BrowserResponse::err(format!("ReadPage failed: {e}")),
        }
    }

    async fn cmd_scroll(&self, direction: &str, amount: i32) -> BrowserResponse {
        let (dx, dy) = match direction {

View on GitHub (pinned to acf2587e46)

Solutions

  1. Read the interpolated {e} for the CDP-level cause.
  2. Retry the screenshot after wait_for_load completes — avoid capturing mid-navigation.
  3. Reconnect/restart the browser session if the connection dropped.
  4. Reduce viewport size or use format options if the capture times out on huge pages.

Example fix

// before
let shot = browser.execute("screenshot", "").await?;
// after
browser.wait_for_load().await?;
let shot = match browser.execute("screenshot", "").await {
    Ok(s) => s,
    Err(_) => {
        tokio::time::sleep(std::time::Duration::from_millis(300)).await;
        browser.execute("screenshot", "").await?
    }
};
Defensive patterns

Strategy: retry

Validate before calling

// Only screenshot a settled page:
browser.wait_for_load().await?;
if !browser.is_connected().await { browser.reconnect().await?; }

Type guard

fn screenshot_payload_valid(resp: &BrowserResponse) -> bool {
    resp.success && resp.value.get("image_base64").and_then(|v| v.as_str()).map_or(false, |s| !s.is_empty())
}

Try / catch

// Rust
let shot = match browser.execute("screenshot", "").await {
    Ok(s) if s.success => Ok(s),
    Ok(s) => Err(anyhow!(s.error)),
    Err(_) => {
        tokio::time::sleep(Duration::from_millis(300)).await;
        browser.execute("screenshot", "").await.map_err(Into::into)
    }
};

Prevention

When it happens

Trigger: 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).

Common situations: Capturing during a navigation or while the tab is being closed; headless Chrome crashed; very large viewport causing the capture to fail/timeout.

Related errors


AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02). Data as JSON: /api/errors/5ad6f873e4ce8fdf. Report an issue: GitHub.