ianstormtaylor/slate · error · Error

Cannot resolve a Slate range from a DOM event: ${event}

Error message

Cannot resolve a Slate range from a DOM event: ${event}

What it means

Thrown by DOMEditor.findEventRange when a DOM event cannot be converted to a Slate range because it lacks clientX/clientY coordinates. Slate needs pointer coordinates to compute a DOM caret position from the event; without them no range can be resolved.

Source

Thrown at packages/slate-dom/src/plugin/dom-editor.ts:322

    const el = DOMEditor.toDOMNode(editor, editor)
    const root = el.getRootNode()

    if (root instanceof Document || root instanceof ShadowRoot) {
      return root
    }

    return el.ownerDocument
  },

  findEventRange: (editor, event) => {
    if ('nativeEvent' in event) {
      event = event.nativeEvent
    }

    const { clientX: x, clientY: y, target } = event

    if (x == null || y == null) {
      throw new Error(`Cannot resolve a Slate range from a DOM event: ${event}`)
    }

    const node = DOMEditor.toSlateNode(editor, event.target)
    const path = DOMEditor.findPath(editor, node)

    // If the drop target is inside a void node, move it into either the
    // next or previous node, depending on which side the `x` and `y`
    // coordinates are closest to.
    if (Node.isElement(node) && Editor.isVoid(editor, node)) {
      const rect = target.getBoundingClientRect()
      const isPrev = editor.isInline(node)
        ? x - rect.left < rect.left + rect.width - x
        : y - rect.top < rect.top + rect.height - y

      const edge = Editor.point(editor, path, {
        edge: isPrev ? 'start' : 'end',
      })
      const point = isPrev

View on GitHub (pinned to 72a37c701e)

Solutions

  1. Ensure you pass a real pointer event (mousedown, mouseup, drop, contextmenu) with coordinates
  2. If using React, pass the event synchronously before pooling or use event.nativeEvent yourself
  3. If you only need the current selection, use editor.selection instead of findEventRange
  4. For custom menus, capture coordinates at trigger time and construct the range manually with document.caretRangeFromPoint/caretPositionFromPoint

Example fix

// before
const range = DOMEditor.findEventRange(editor, someKeyboardEvent)
// after
const range = editor.selection ?? DOMEditor.findEventRange(editor, pointerEvent)
Defensive patterns

Strategy: validation

Validate before calling

const e = event.nativeEvent ?? event
if (e.clientX == null || e.clientY == null) {
  // not a resolvable pointer event; use current selection instead
  return editor.selection
}

Type guard

const isPointerLikeEvent = (e: any): e is MouseEvent =>
  typeof e?.clientX === 'number' && typeof e?.clientY === 'number'

Try / catch

try { DOMEditor.findEventRange(editor, event) } catch (e) { if (e.message.includes('Cannot resolve a Slate range')) fallback to editor.selection; else throw e }

Prevention

When it happens

Trigger: Calling editor.findEventRange(event) (e.g. in a custom paste, drop, or context-menu handler) with an event that has no clientX/clientY — typically a synthesized/Polymer-wrapped event, a keyboard event, or an event whose nativeEvent was not passed.

Common situations: Passing a React synthetic event after it was pooled/nullified, passing a CustomEvent or keyboard event to findEventRange, or frameworks that wrap native events so clientX/clientY are undefined at read time.

Related errors


AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27). Data as JSON: /api/errors/0ab9007e0bfd725a. Report an issue: GitHub.