ianstormtaylor/slate · error · Error

Unable to find the path for Slate node: ${Scrubber.stringify

Error message

Unable to find the path for Slate node: ${Scrubber.stringify(node)}

What it means

Thrown by DOMEditor.findPath when walking up from a Slate node to the root via parent links fails to reach the root editor. This means the node is not attached to this editor's tree (detached, from another editor, or a stale reference after normalization).

Source

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

      if (parent == null) {
        if (child === editor) {
          return path
        } else {
          break
        }
      }

      const i = NODE_TO_INDEX.get(child)

      if (i == null) {
        break
      }

      path.unshift(i)
      child = parent
    }

    throw new Error(
      `Unable to find the path for Slate node: ${Scrubber.stringify(node)}`
    )
  },

  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.

View on GitHub (pinned to 72a37c701e)

Solutions

  1. Re-resolve the node from the DOM right before finding its path
  2. Do not cache Slate node objects across editing operations; store paths or keys instead
  3. Perform the lookup synchronously within the same change cycle
  4. Verify the node belongs to this editor with Node.has(editor, path) or key comparison

Example fix

// before
const savedNode = DOMEditor.toSlateNode(editor, el)
// ... later after edits
const path = DOMEditor.findPath(editor, savedNode)
// after
const node = DOMEditor.toSlateNode(editor, el) // fresh
const path = DOMEditor.findPath(editor, node)
Defensive patterns

Strategy: validation

Validate before calling

const node = DOMEditor.toSlateNode(editor, domEl)
const path = DOMEditor.findPath(editor, node) // only safe synchronously
// validate a cached node still belongs:
try { Node.get(editor, DOMEditor.findPath(editor, node)) } catch { /* stale */ }

Type guard

null

Try / catch

try { path = DOMEditor.findPath(editor, node) } catch (e) { if (/Unable to find the path/.test(e.message)) re-resolve node from DOM; else throw e }

Prevention

When it happens

Trigger: Calling toSlateNode/findPath with a DOM element whose mapped Slate node was removed by normalization, or calling editor.findPath on a node object captured before a normalize/apply pass removed it.

Common situations: Keeping stale node references across edits (normalization replaces nodes), rendering one editor's node in another editor, or reading paths during an asynchronous callback after the document changed.

Related errors


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