RightNow-AI/openfang · error · BrowserResponse

Type failed

Error message

Type failed

What it means

cmd_type evaluates injected JS that focuses the selector's element and types text, returning {success, error} JSON. When the script reports success=false, this fallback message is used if no 'error' string was returned — the DOM-side type action itself failed (element missing, not editable).

Source

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

    let txt = {text_json};
    let el = document.querySelector(sel);
    if (!el) return JSON.stringify({{success: false, error: 'Input not found: ' + sel}});
    el.focus();
    el.value = txt;
    el.dispatchEvent(new Event('input', {{bubbles: true}}));
    el.dispatchEvent(new Event('change', {{bubbles: true}}));
    return JSON.stringify({{success: true, selector: sel, typed: txt.length + ' chars'}});
}})()"#
        );

        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) {
                    BrowserResponse::err(parsed["error"].as_str().unwrap_or("Type failed"))
                } else {
                    BrowserResponse::ok(parsed)
                }
            }
            Err(e) => BrowserResponse::err(format!("Type failed: {e}")),
        }
    }

    async fn cmd_screenshot(&self) -> BrowserResponse {
        match self
            .cdp
            .send(
                "Page.captureScreenshot",
                serde_json::json!({ "format": "png" }),
            )
            .await
        {
            Ok(result) => {

View on GitHub (pinned to acf2587e46)

Solutions

  1. Verify the selector targets an editable input/textarea/contenteditable element.
  2. Wait for the element first (cmd_wait) before typing.
  3. Check the parsed error field for a more specific script-side reason.
  4. For framework-managed inputs, use events (input/change) in the typing script so state updates.

Example fix

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

Strategy: validation

Validate before calling

// Verify the target is an editable element before typing:
let js = format!(
    "(() => {{ const el = document.querySelector({sel_json}); \
      return !!el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.isContentEditable); }})()",
    sel_json = serde_json::to_string(selector).unwrap_or_default()
);
let editable = browser.run_js(&js).await?; // must be true before cmd_type

Type guard

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

Try / catch

// Rust
let resp = browser.execute("type", &format!("{selector}|{text}")).await?;
if !resp.success {
    if resp.error == "Type failed" {
        browser.execute("wait", &format!("{selector}|3000")).await?;
        return browser.execute("type", &format!("{selector}|{text}")).await.map_err(Into::into);
    }
    return Err(anyhow!(resp.error));
}
Ok(resp)

Prevention

When it happens

Trigger: The type JS over CDP returns parsed["success"] == false with parsed["error"] absent or not a string — e.g. selector matched nothing so the script reported failure without a message.

Common situations: Typing into a readonly/disabled input; selector matching a non-input element; element not yet rendered when type is called; React-controlled inputs rejecting naive value assignment.

Related errors


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