RightNow-AI/openfang · error · BrowserResponse

Click failed

Error message

Click failed

What it means

cmd_click evaluates a JS snippet via CDP that clicks the element matching a selector and returns {success, error} JSON. When the script reports success=false, this fallback message 'Click failed' is used if the script did not include an 'error' string — i.e. the click script itself determined the click could not be performed (element not found, not clickable).

Source

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

        for (const e of all) {{
            if (e.textContent.trim().toLowerCase().includes(lower)) {{ el = e; break; }}
        }}
    }}
    if (!el) return JSON.stringify({{success: false, error: 'Element not found: ' + sel}});
    el.scrollIntoView({{block: 'center'}});
    el.click();
    return JSON.stringify({{success: true, tag: el.tagName, text: el.textContent.substring(0, 100).trim()}});
}})()"#
        );

        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);
                if parsed["success"].as_bool() == Some(false) {
                    return BrowserResponse::err(
                        parsed["error"]
                            .as_str()
                            .unwrap_or("Click failed")
                            .to_string(),
                    );
                }
                // Wait briefly for any navigation triggered by click
                tokio::time::sleep(Duration::from_millis(500)).await;
                self.wait_for_load().await;
                match self.page_info().await {
                    Ok(info) => BrowserResponse::ok(info),
                    Err(_) => BrowserResponse::ok(parsed),
                }
            }
            Err(e) => BrowserResponse::err(format!("Click failed: {e}")),
        }
    }

View on GitHub (pinned to acf2587e46)

Solutions

  1. Verify the selector matches exactly one visible element (test it in the browser console with document.querySelector).
  2. Use cmd_wait on the selector before clicking to ensure it exists in the DOM.
  3. Inspect the parsed error payload — the script usually returns a more specific 'error' field than this fallback.
  4. For shadow DOM or iframes, use a selector strategy that penetrates them or switch frames first.

Example fix

// before
let _ = browser.execute("click", selector).await?;
// after
browser.execute("wait", &format!("{selector}|5000")).await?;
let resp = browser.execute("click", selector).await?;
if !resp.success { return Err(anyhow!(resp.error)); }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the element exists before clicking:
let wait = browser.execute("wait", &format!("{selector}|5000")).await?;
if !wait.success { return Err(anyhow!("element not present: {selector}")); }

Type guard

fn click_failed_no_reason(resp: &BrowserResponse) -> bool {
    !resp.success && resp.error == "Click failed"
}

Try / catch

// Rust
let resp = browser.execute("click", selector).await?;
if !resp.success {
    if resp.error == "Click failed" {
        // no script-side reason — most likely selector miss; wait and retry once
        browser.execute("wait", &format!("{selector}|3000")).await?;
        return browser.execute("click", selector).await.map_err(Into::into);
    }
    return Err(anyhow!(resp.error));
}
Ok(resp)

Prevention

When it happens

Trigger: Running the click JS over CDP returns a value whose parsed["success"] is false and parsed["error"] is missing or not a string — e.g. the injected script failed to find the selector and returned success:false without a message.

Common situations: Selector typo or element rendered client-side after the click attempt; element inside an iframe the script doesn't reach; stale selector after a re-render.

Related errors


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