{"record":{"id":"319b8997f4c69859","repo":"ianstormtaylor/slate","slug":"could-not-set-focus-editor-seems-stuck-with-pendi","errorCode":null,"errorMessage":"Could not set focus, editor seems stuck with pending operations","messagePattern":"Could not set focus, editor seems stuck with pending operations","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/slate-dom/src/plugin/dom-editor.ts","lineNumber":436,"sourceCode":"  },\n\n  focus: (editor, options = { retries: 5 }) => {\n    // Return if already focused\n    if (IS_FOCUSED.get(editor)) {\n      return\n    }\n\n    // Return if no dom node is associated with the editor, which means the editor is not yet mounted\n    // or has been unmounted. This can happen especially, while retrying to focus the editor.\n    if (!EDITOR_TO_ELEMENT.get(editor)) {\n      return\n    }\n\n    // Retry setting focus if the editor has pending operations.\n    // The DOM (selection) is unstable while changes are applied.\n    // Retry until retries are exhausted or editor is focused.\n    if (options.retries <= 0) {\n      throw new Error(\n        'Could not set focus, editor seems stuck with pending operations'\n      )\n    }\n    if (editor.operations.length > 0) {\n      setTimeout(() => {\n        DOMEditor.focus(editor, { retries: options.retries - 1 })\n      }, 10)\n      return\n    }\n\n    const el = DOMEditor.toDOMNode(editor, editor)\n    const root = DOMEditor.findDocumentOrShadowRoot(editor)\n    if (root.activeElement !== el) {\n      // Ensure that the DOM selection state is set to the editor's selection\n      if (editor.selection && root instanceof Document) {\n        const domSelection = getSelection(root)\n        const domRange = DOMEditor.toDOMRange(editor, editor.selection)\n        domSelection?.removeAllRanges()","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/ianstormtaylor/slate/blob/72a37c701e5da4bb13a305d416d9c070d19d3a45/packages/slate-dom/src/plugin/dom-editor.ts#L418-L454","documentation":"Thrown by DOMEditor.focus after retrying (default 5 times, ~via setTimeout) while the editor still has pending operations, because setting selection/focus during in-flight changes is unstable. It indicates the editor is stuck with a non-empty editor.operations queue.","triggerScenarios":"Calling editor.focus() repeatedly while editor.operations.length never drains — e.g. focus called inside a change loop, a bug elsewhere leaves operations on the queue, or overlapping asynchronous focus retries.","commonSituations":"Calling focus() inside onChange or a withOverride, an unhandled error aborting a change so operations never clear, or custom editor implementations that mutate editor.operations.","solutions":["Call focus outside of change/onChange cycles (e.g. in useEffect after render)","Check editor.operations.length before focusing and defer with setTimeout if non-empty","Increase retries via DOMEditor.focus(editor, { retries: 10 })","Audit custom plugins/normalizers that may throw mid-change and leave operations pending"],"exampleFix":"// before\neditor.insertText('x')\nDOMEditor.focus(editor) // inside same change\n// after\neditor.insertText('x')\nsetTimeout(() => DOMEditor.focus(editor))","handlingStrategy":"retry","validationCode":"if (editor.operations.length === 0) {\n  DOMEditor.focus(editor)\n} else {\n  setTimeout(() => DOMEditor.focus(editor, { retries: 10 }))\n}","typeGuard":"null","tryCatchPattern":"try { DOMEditor.focus(editor, { retries: 10 }) } catch (e) { if (/Could not set focus/.test(e.message)) schedule another retry or surface a warning; else throw e }","preventionTips":["Call focus() outside onChange/change cycles","Keep focus calls in useEffect after commit","Audit plugins that throw mid-change and strand operations"],"tags":["slate","focus","retries","pending-operations"],"backgroundTag":"editor-focus-stuck","analyzedSha":"72a37c701e5da4bb13a305d416d9c070d19d3a45","analyzedAt":"2026-08-27T23:04:51.145Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}