Kuberwastaken/claurst · error

No element found for selector

Error message

No element found for selector: {}

What it means

Thrown by the `click` command when the injected Runtime.evaluate JavaScript reports the sentinel value "ELEMENT_NOT_FOUND" instead of element coordinates. This means document.querySelector found no match for the given selector in the page DOM, so no click coordinates can be computed.

Solutions

  1. Verify the selector matches in the page (test with `/chrome eval document.querySelector('<selector>') !== null`).
  2. Wait for the page to finish loading before clicking, or navigate explicitly first.
  3. Fix the selector — check for typos, iframes, or shadow-DOM boundaries.
  4. Use a more general selector or add an explicit wait/retry before the click.

Example fix

// before: immediate click on a not-yet-rendered element
chrome_click("#submit")?;

// after: wait until the element exists
chrome_eval("document.querySelector('#submit') !== null")?; // poll if false
chrome_click("#submit")?;
Defensive patterns

Strategy: validation

Validate before calling

let found: bool = cdp_eval("document.querySelector('<selector>') !== null").await?;
if !found { /* wait, fix selector, or bail before clicking */ }

Type guard

async fn element_exists(ws: &mut Ws, selector: &str) -> bool {
    let expr = format!("document.querySelector({:?}) !== null", selector);
    let resp = cdp_call(ws, "Runtime.evaluate", json!({"expression": expr, "returnByValue": true})).await.ok()?;
    resp["result"]["result"]["value"].as_bool().unwrap_or(false)
}

Try / catch

match click(selector).await {
    Ok(_) => {},
    Err(e) if e.to_string().contains("No element found") => {
        wait_for_selector(selector).await?;
        click(selector).await?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `/chrome click <selector>` where the selector matches no element in the current tab's DOM; page still loading so the element is not yet rendered; selector typo or wrong frame/iframe context.

Common situations: Automating a SPA before hydration completes; clicking an element inside an iframe (querySelector at top level cannot see it); stale selectors after a site redesign; shadow-DOM elements not reachable via plain querySelector.

Related errors


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/756465e08bfcdb02. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/commands/src/chrome.rs:241

                var el=document.querySelector({sel});
                if(!el)return 'ELEMENT_NOT_FOUND';
                var r=el.getBoundingClientRect();
                return JSON.stringify({{x:r.left+r.width/2,y:r.top+r.height/2}});
            }})()"#,
            sel = sel_json
        );
        let selector = selector.to_string();
        let mut s = take_session()?;
        let result = async {
            let resp = cdp_call(
                &mut s.ws,
                "Runtime.evaluate",
                json!({ "expression": js, "returnByValue": true }),
            )
            .await?;
            let val_str = resp["result"]["result"]["value"].as_str().unwrap_or("");
            if val_str == "ELEMENT_NOT_FOUND" {
                return Err(anyhow::anyhow!(
                    "No element found for selector: {}",
                    selector
                ));
            }
            let coords: Value = serde_json::from_str(val_str)?;
            let x = coords["x"].as_f64().unwrap_or(0.0);
            let y = coords["y"].as_f64().unwrap_or(0.0);

            cdp_call(
                &mut s.ws,
                "Input.dispatchMouseEvent",
                json!({
                    "type": "mousePressed", "x": x, "y": y,
                    "button": "left", "clickCount": 1
                }),
            )
            .await?;
            cdp_call(

View on GitHub (pinned to b0637c97ec)