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
- 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.
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
- 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.
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
- Navigate failed: {e}
- Screenshot failed: {e}
- Scroll failed: {e}
- Navigate succeeded but page info failed: {e}
- Click failed
AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02).
Data as JSON: /api/errors/ddd817f057a41f64.
Report an issue: GitHub.