Kuberwastaken/claurst · error
No debuggable page found on port
Error message
No debuggable page found on port {}. Make sure Chrome has at least one open tab. What it means
Thrown by `connect` when querying Chrome's DevTools HTTP endpoint (`/json` list of targets) yields no target of type "page" with a webSocketDebuggerUrl. Chrome is reachable on the debug port but exposes no debuggable page target, so the library cannot obtain a CDP WebSocket URL and aborts the connect.
Solutions
- Open at least one normal tab in the Chrome instance being debugged.
- Restart Chrome with --remote-debugging-port=<port> and an initial URL so a page target exists.
- Verify with `curl http://127.0.0.1:<port>/json` that a target with "type":"page" and webSocketDebuggerUrl appears.
- Re-run `/chrome connect` after the tab is open.
Example fix
// before: chrome started with no tabs // http://127.0.0.1:9222/json returns only service workers // after: start chrome with an initial page // chrome --remote-debugging-port=9222 https://example.com
Defensive patterns
Strategy: retry
Validate before calling
let targets: Value = reqwest::get(format!("http://127.0.0.1:{}/json", port)).await?.json().await?;
let ok = targets.as_array().map(|a| a.iter().any(|t| t["type"] == "page" && t.get("webSocketDebuggerUrl").is_some())).unwrap_or(false);
if !ok { /* open a tab or restart Chrome */ } Type guard
fn has_page_target(targets: &Value) -> bool {
targets.as_array().is_some_and(|a| a.iter().any(|t| t["type"] == "page" && t["webSocketDebuggerUrl"].is_string()))
} Try / catch
match connect(port).await {
Ok(_) => {},
Err(e) if e.to_string().contains("No debuggable page") => {
open_new_tab(port)?;
connect(port).await?;
}
Err(e) => return Err(e),
} Prevention
- Start Chrome with an initial URL so a page target always exists.
- Verify /json output shows a "type":"page" target before connecting.
- Avoid closing all tabs in a debugged Chrome instance.
When it happens
Trigger: Chrome runs with --remote-debugging-port but has zero open tabs (all closed, only background/service-worker targets present); the target list JSON has no entry whose `type` equals "page" or whose `webSocketDebuggerUrl` field is absent.
Common situations: Headless Chrome started without an initial URL and all tabs closed; Chrome started with a --remote-debugging-port only reachable in new window modes where no page target exists yet; enterprise Chrome policies hiding debug targets.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- WebSocket closed unexpectedly
- WebSocket closed by Chrome
- WebSocket connect to
- CDP error
- No screenshot data in response
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/3baf9ce7103d8c9e.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/commands/src/chrome.rs:129
/// Connect to Chrome at the given port.
/// Picks the first available target (tab/page).
pub async fn connect(port: u16) -> anyhow::Result<String> {
let http_url = format!("http://localhost:{}/json/list", port);
let client = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(3))
.build()?;
let tabs: Value = client.get(&http_url).send().await?.json().await?;
let ws_url = tabs
.as_array()
.and_then(|arr| {
arr.iter().find(|t| t["type"] == "page").and_then(|t| {
t["webSocketDebuggerUrl"].as_str().map(|s| s.to_string())
})
})
.ok_or_else(|| {
anyhow::anyhow!(
"No debuggable page found on port {}. \
Make sure Chrome has at least one open tab.",
port
)
})?;
let tab_url = tabs
.as_array()
.and_then(|arr| {
arr.iter()
.find(|t| t["type"] == "page")
.and_then(|t| t["url"].as_str().map(|s| s.to_string()))
})
.unwrap_or_default();
let (ws, _) = connect_async(&ws_url).await.map_err(|e| {
anyhow::anyhow!("WebSocket connect to {} failed: {}", ws_url, e)
})?;
View on GitHub (pinned to b0637c97ec)