ianstormtaylor/slate · error · Error
Could not set focus, editor seems stuck with pending operati
Error message
Could not set focus, editor seems stuck with pending operations
What it means
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.
Source
Thrown at packages/slate-dom/src/plugin/dom-editor.ts:436
},
focus: (editor, options = { retries: 5 }) => {
// Return if already focused
if (IS_FOCUSED.get(editor)) {
return
}
// Return if no dom node is associated with the editor, which means the editor is not yet mounted
// or has been unmounted. This can happen especially, while retrying to focus the editor.
if (!EDITOR_TO_ELEMENT.get(editor)) {
return
}
// Retry setting focus if the editor has pending operations.
// The DOM (selection) is unstable while changes are applied.
// Retry until retries are exhausted or editor is focused.
if (options.retries <= 0) {
throw new Error(
'Could not set focus, editor seems stuck with pending operations'
)
}
if (editor.operations.length > 0) {
setTimeout(() => {
DOMEditor.focus(editor, { retries: options.retries - 1 })
}, 10)
return
}
const el = DOMEditor.toDOMNode(editor, editor)
const root = DOMEditor.findDocumentOrShadowRoot(editor)
if (root.activeElement !== el) {
// Ensure that the DOM selection state is set to the editor's selection
if (editor.selection && root instanceof Document) {
const domSelection = getSelection(root)
const domRange = DOMEditor.toDOMRange(editor, editor.selection)
domSelection?.removeAllRanges()View on GitHub (pinned to 72a37c701e)
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
Example fix
// before
editor.insertText('x')
DOMEditor.focus(editor) // inside same change
// after
editor.insertText('x')
setTimeout(() => DOMEditor.focus(editor)) Defensive patterns
Strategy: retry
Validate before calling
if (editor.operations.length === 0) {
DOMEditor.focus(editor)
} else {
setTimeout(() => DOMEditor.focus(editor, { retries: 10 }))
} Type guard
null
Try / catch
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 } Prevention
- Call focus() outside onChange/change cycles
- Keep focus calls in useEffect after commit
- Audit plugins that throw mid-change and strand operations
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Slate hyperscript ranges must have both `<anchor />` and `<f
- Cannot resolve a Slate range from a DOM event: ${event}
- Unable to find the path for Slate node: ${Scrubber.stringify
- Unable to find a host window element for this editor
- Cannot resolve a DOM node from Slate node: ${Scrubber.string
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/319b8997f4c69859.
Report an issue: GitHub.