RightNow-AI/openfang · error · BrowserResponse

ReadPage failed: {e}

Error message

ReadPage failed: {e}

What it means

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.

Source

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

                    .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 {
            "up" => (0, -amount),
            "down" => (0, amount),
            "left" => (-amount, 0),
            "right" => (amount, 0),
            _ => (0, amount),
        };
        let js = format!("window.scrollBy({dx}, {dy}); JSON.stringify({{scrollX: window.scrollX, scrollY: window.scrollY}})");
        match self.cdp.run_js(&js).await {
            Ok(val) => {
                let parsed: serde_json::Value = val
                    .as_str()
                    .and_then(|s| serde_json::from_str(s).ok())
                    .unwrap_or(val);

View on GitHub (pinned to acf2587e46)

Solutions

  1. Read the interpolated {e} for the underlying CDP cause.
  2. Wait for load completion and retry read_page once before surfacing the error.
  3. Reconnect the browser session if the connection dropped.
  4. If extraction times out on heavy pages, narrow extraction (e.g. main/article element) to reduce work.

Example fix

// before
let content = browser.execute("read_page", "").await?;
// after
let content = match browser.execute("read_page", "").await {
    Ok(c) => c,
    Err(_) => {
        browser.wait_for_load().await?;
        browser.execute("read_page", "").await?
    }
};
Defensive patterns

Strategy: retry

Validate before calling

// Ensure the page is loaded and connected before extraction:
browser.wait_for_load().await?;
if !browser.is_connected().await { browser.reconnect().await?; }

Type guard

fn extract_has_content(resp: &BrowserResponse) -> bool {
    resp.success && match &resp.value {
        serde_json::Value::Object(m) => !m.is_empty(),
        serde_json::Value::String(s) => !s.trim().is_empty(),
        _ => false,
    }
}

Try / catch

// Rust
let content = match browser.execute("read_page", "").await {
    Ok(c) if c.success => Ok(c),
    Ok(c) => Err(anyhow!(c.error)),
    Err(_) => {
        browser.wait_for_load().await?;
        browser.execute("read_page", "").await.map_err(Into::into)
    }
};

Prevention

When it happens

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

Common situations: 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.

Related errors


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