alibaba/page-agent · error · Error
Element is not an input, textarea, or contenteditable
Error message
Element is not an input, textarea, or contenteditable
What it means
inputTextElement only accepts <input>, <textarea>, or contenteditable elements; anything else (div, button, span) throws this error. Text entry requires a value-bearing or editable surface, so the library validates the element kind before typing. Receiving a non-editable element usually means the wrong index was chosen or the element role changed.
Source
Thrown at packages/page-controller/src/actions.ts:134
// Release
target.dispatchEvent(new PointerEvent('pointerup', pointerOpts))
target.dispatchEvent(new MouseEvent('mouseup', mouseOpts))
// Click — activation behavior (navigation, form submit, etc.) triggers
// via bubbling from target up to the interactive ancestor.
target.click()
await waitFor(0.2)
}
/**
* @private Internal method, subject to change at any time.
*/
export async function inputTextElement(element: HTMLElement, text: string) {
const isContentEditable = element.isContentEditable
if (!isInputElement(element) && !isTextAreaElement(element) && !isContentEditable) {
throw new Error('Element is not an input, textarea, or contenteditable')
}
await clickElement(element)
if (isContentEditable) {
// Contenteditable support (partial)
// Not supported:
// - Monaco/CodeMirror: Require direct JS instance access. No universal way to obtain.
// - Draft.js: Not responsive to synthetic/execCommand/Range/DataTransfer. Unmaintained.
//
// Strategy: Try Plan A (synthetic events) first, then verify and fall back
// to Plan B (execCommand) if the text wasn't actually inserted.
//
// Plan A: Dispatch synthetic events
// Works: React contenteditable, Quill.
// Fails: Slate.js, some contenteditable editors that ignore synthetic events.
// Sequence: beforeinput -> mutation -> input -> change -> blur
View on GitHub (pinned to d02db1ee7c)
Solutions
- Inspect the simplified HTML and target the index of the actual <input>/<textarea> or a contenteditable node
- For wrapper components, click the wrapper first to focus, then find the revealed input and type into it
- Guard before typing: check element.tagName or isContentEditable
- If the site uses a fake-input div, consider dispatching keyboard events instead of inputText
Example fix
// before await controller.inputText(12, 'query') // index 12 is a <div> // after await controller.updateTree() // find the real input element index (e.g. 13) in getSimplifiedHTML() await controller.inputText(13, 'query')
Defensive patterns
Strategy: type-guard
Validate before calling
const el = await controller.element(i); if (!el) return; if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) && !el.isContentEditable) { /* click to reveal the real input, re-index, skip inputText */ } Type guard
function isTextEntryTarget(el: HTMLElement): boolean { return el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el.isContentEditable } Try / catch
try { await controller.inputText(i, text) } catch (e) { if (String(e).includes('not an input, textarea, or contenteditable')) { await controller.clickElement(i); await controller.updateTree(); /* find revealed input */ } else throw e } Prevention
- Target the inner input/textarea index, not the visible wrapper
- Verify editability from the simplified HTML before typing
- For rich-text UIs, confirm a contenteditable attribute exists
When it happens
Trigger: Calling inputText on an index pointing to a <div>, <button>, <label>, or any non-editable element; the input was replaced by a rich-text div that is not contenteditable; acting on a container/wrapper instead of the inner <input> (common with custom dropdowns and search boxes).
Common situations: LLM picks the visible label/wrapper instead of the inner input; custom components render a fake input div without contenteditable; the field switched to readonly/disabled custom widget between observation and action.
Related errors
- DOM tree not indexed yet. Can not perform actions on element
- No interactive element found at index ${index}
- Element at index ${index} does not have a reference
- Element at index ${index} is not an HTMLElement
- Element is not a select element
AI-assisted analysis of alibaba/page-agent@d02db1ee7c (2026-08-28).
Data as JSON: /api/errors/172263e472cdb5c6.
Report an issue: GitHub.