{"record":{"id":"4f72a7f38f680deb","repo":"RightNow-AI/openfang","slug":"type-failed","errorCode":null,"errorMessage":"Type failed","messagePattern":"Type failed","errorType":"error_code","errorClass":"BrowserResponse","httpStatus":null,"severity":"error","filePath":"crates/openfang-runtime/src/browser.rs","lineNumber":507,"sourceCode":"    let txt = {text_json};\n    let el = document.querySelector(sel);\n    if (!el) return JSON.stringify({{success: false, error: 'Input not found: ' + sel}});\n    el.focus();\n    el.value = txt;\n    el.dispatchEvent(new Event('input', {{bubbles: true}}));\n    el.dispatchEvent(new Event('change', {{bubbles: true}}));\n    return JSON.stringify({{success: true, selector: sel, typed: txt.length + ' chars'}});\n}})()\"#\n        );\n\n        match self.cdp.run_js(&js).await {\n            Ok(val) => {\n                let parsed: serde_json::Value = val\n                    .as_str()\n                    .and_then(|s| serde_json::from_str(s).ok())\n                    .unwrap_or(val);\n                if parsed[\"success\"].as_bool() == Some(false) {\n                    BrowserResponse::err(parsed[\"error\"].as_str().unwrap_or(\"Type failed\"))\n                } else {\n                    BrowserResponse::ok(parsed)\n                }\n            }\n            Err(e) => BrowserResponse::err(format!(\"Type failed: {e}\")),\n        }\n    }\n\n    async fn cmd_screenshot(&self) -> BrowserResponse {\n        match self\n            .cdp\n            .send(\n                \"Page.captureScreenshot\",\n                serde_json::json!({ \"format\": \"png\" }),\n            )\n            .await\n        {\n            Ok(result) => {","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/RightNow-AI/openfang/blob/acf2587e46be174c10200489c9a2d23a39a98aeb/crates/openfang-runtime/src/browser.rs#L489-L525","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the selector targets an editable input/textarea/contenteditable element.","Wait for the element first (cmd_wait) before typing.","Check the parsed error field for a more specific script-side reason.","For framework-managed inputs, use events (input/change) in the typing script so state updates."],"exampleFix":"// before\nbrowser.execute(\"type\", &format!(\"{selector}|{text}\")).await?;\n// after\nbrowser.execute(\"wait\", &format!(\"{selector}|5000\")).await?;\nlet resp = browser.execute(\"type\", &format!(\"{selector}|{text}\")).await?;\nif !resp.success { return Err(anyhow!(resp.error)); }","handlingStrategy":"validation","validationCode":"// Verify the target is an editable element before typing:\nlet js = format!(\n    \"(() => {{ const el = document.querySelector({sel_json}); \\\n      return !!el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.isContentEditable); }})()\",\n    sel_json = serde_json::to_string(selector).unwrap_or_default()\n);\nlet editable = browser.run_js(&js).await?; // must be true before cmd_type","typeGuard":"fn type_failed_no_reason(resp: &BrowserResponse) -> bool {\n    !resp.success && resp.error == \"Type failed\"\n}","tryCatchPattern":"// Rust\nlet resp = browser.execute(\"type\", &format!(\"{selector}|{text}\")).await?;\nif !resp.success {\n    if resp.error == \"Type failed\" {\n        browser.execute(\"wait\", &format!(\"{selector}|3000\")).await?;\n        return browser.execute(\"type\", &format!(\"{selector}|{text}\")).await.map_err(Into::into);\n    }\n    return Err(anyhow!(resp.error));\n}\nOk(resp)","preventionTips":["Wait for the element before typing.","Confirm the element is input/textarea/contenteditable.","Skip typing into readonly or disabled fields.","Use input/change event dispatch for framework-controlled inputs."],"tags":["selector","dom-input","browser-automation"],"backgroundTag":"element-not-found","analyzedSha":"acf2587e46be174c10200489c9a2d23a39a98aeb","analyzedAt":"2026-09-02T22:42:28.464Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}