{"record":{"id":"f8d05e3296992db9","repo":"stablyai/orca","slug":"focused-rich-text-target-is-unavailable","errorCode":null,"errorMessage":"Focused rich-text target is unavailable","messagePattern":"Focused rich-text target is unavailable","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/browser/agent-browser-bridge.ts","lineNumber":134,"sourceCode":"    ' } })()'\n  ].join('')\n}\n\n// Why: rich editors reconcile only real browser edit transactions; a direct-DOM fallback can leave their model stale.\nfunction focusedRichTextEditExpression(\n  valueExpression: string,\n  options?: { selectAll?: boolean }\n): string {\n  const selectAll = options?.selectAll ? 'true' : 'false'\n  return [\n    '(() => {',\n    ' const target = document.activeElement;',\n    ' const value = ',\n    valueExpression,\n    ';',\n    ` const selectAll = ${selectAll};`,\n    \" const isEditable = target?.isContentEditable === true || /^(|true|plaintext-only)$/i.test(target?.getAttribute?.('contenteditable') ?? 'false');\",\n    \" if (!target || target === document.body || !isEditable) { throw new Error('Focused rich-text target is unavailable'); }\",\n    ' if (selectAll) {',\n    \"   if (typeof window.getSelection !== 'function') { throw new Error('Rich-text selection is unavailable'); }\",\n    '   const selection = window.getSelection();',\n    \"   if (!selection) { throw new Error('Rich-text selection is unavailable'); }\",\n    '   selection.selectAllChildren(target);',\n    ' }',\n    \" const editCommand = selectAll && value.length === 0 ? 'delete' : 'insertText';\",\n    ' let edited = false;',\n    ' try {',\n    '   edited = document.execCommand(editCommand, false, value) === true;',\n    ' } catch { edited = false; }',\n    \" if (!edited) { throw new Error('Browser rich-text editing command failed'); }\",\n    ' })()'\n  ].join('')\n}\n\nfunction isExplicitContentEditableResult(result: unknown): boolean {\n  const value =","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/browser/agent-browser-bridge.ts#L116-L152","documentation":"Thrown by injected JavaScript that focusedRichTextEditExpression builds and evaluates inside the browser page. It fires when document.activeElement is null, is document.body, or is not contentEditable (neither isContentEditable nor a 'true'/'plaintext-only' contenteditable attribute). The bridge requires a real editable host to drive edits through the browser's own input pipeline so rich editors (ProseMirror, etc.) reconcile correctly.","triggerScenarios":"Calling fill on an element while focus has moved away from the editable target — e.g. the page blurred it, a modal stole focus, the element was never focused first, or the selector resolved to a non-editable node (plain div, span, or body).","commonSituations":"Filling a rich editor that lazily mounts, focus lost to a popup/autocomplete between the focus step and the eval, filling a non-contentEditable element by mistake, or a page that programmatically blurs on focus.","solutions":["Ensure the target element is focused and is genuinely contentEditable before filling — call the bridge's focus step and re-check.","Wait for the rich editor to finish mounting before filling (e.g. wait for a contenteditable attribute).","Use the bridge's explicit contenteditable detection (isExplicitContentEditableTarget) to confirm the target type.","Retry the focus+fill sequence once, since transient focus loss is common."],"exampleFix":"// before\nawait bridge.fill('[data-editor]', text)\n\n// after\nawait bridge.focus('[data-editor]')\n// confirm the editor is editable, then fill\nawait bridge.fill('[data-editor]', text)","handlingStrategy":"validation","validationCode":"// run in the page before fill to confirm an editable host is focused:\\nconst isEditable = await bridge.eval(\\n  '(() => { const t = document.activeElement; return !!t && t !== document.body && ' +\\n  '(t.isContentEditable === true || /^(|true|plaintext-only)$/i.test(t.getAttribute?.(\\\"contenteditable\\\") ?? \\\"false\\\")); })()'\\n)\\nif (!isEditable) {\\n  throw new Error('No focused contentEditable target — focus the editor first')\\n}","typeGuard":"async function isFocusedEditable(bridge: BrowserBridge): Promise<boolean> {\\n  return Boolean(await bridge.eval(\\n    '(() => { const t = document.activeElement; return !!t && t !== document.body && (t.isContentEditable === true || /^(|true|plaintext-only)$/i.test(t.getAttribute?.(\\\"contenteditable\\\") ?? \\\"false\\\")); })()'\\n  ))\\n}","tryCatchPattern":"try {\\n  await bridge.focus(selector)\\n  await bridge.fill(selector, text)\\n} catch (err) {\\n  if (/Focused rich-text target is unavailable/.test((err as Error).message)) {\\n    await bridge.focus(selector)\\n    await bridge.fill(selector, text) // one retry\\n    return\\n  }\\n  throw err\\n}","preventionTips":["Always focus the editable element before filling.","Wait for the rich editor to mount (contenteditable attribute present).","Confirm the selector resolves to a contentEditable node.","Retry focus+fill once for transient focus loss."],"tags":["browser","electron","rich-text","contenteditable","dom"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}