Skip to content

RangeError in getParentBlockInfo when pressing Delete at end of last block (regression from #2126) #2584

@hedi-ghodhbane

Description

@hedi-ghodhbane

What's broken?

Pressing the Delete key (forward-delete) when the cursor is at the end of the last block in the document throws:

RangeError: There is no position before the top-level node

The error originates from getParentBlockInfo in mergeBlocks.ts (line 16).

This is a regression introduced in PR #2126 (v0.47.1). The old code had a depth guard:

if ($pos.depth <= 1) {
    return undefined;
}

The new code calls $pos.before(depth) before any guard:

const depth = $pos.depth - 1;
const parentBeforePos = $pos.before(depth); // crashes when depth === 0

When $pos.depth === 1, depth becomes 0, and $pos.before(0) throws because there is no position before the top-level document node.

What did you expect to happen?

Pressing Delete at the end of the last block should be a no-op (nothing to merge with), not throw an uncaught RangeError.

Steps to reproduce

  1. Open any BlockNote editor
  2. Type some text in a single block (e.g. "hello")
  3. Place cursor at the end of the text
  4. Press the Delete key (Fn+Backspace on Mac)
  5. Open browser DevTools console → RangeError: There is no position before the top-level node

Or paste this in the browser console on any page with a BlockNote editor:

(() => {
  const el = document.querySelector('[contenteditable="true"]');
  if (!el) return console.error('No editor found');
  el.focus();
  document.execCommand('insertText', false, 'hello');
  const sel = window.getSelection();
  sel.selectAllChildren(el);
  sel.collapseToEnd();
  el.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', code: 'Delete', bubbles: true }));
  console.log('Check console for RangeError');
})();

Suggested fix

Restore the depth guard before calling $pos.before(depth) in getParentBlockInfo:

export const getParentBlockInfo = (doc: Node, beforePos: number): BlockInfo | undefined => {
  const $pos = doc.resolve(beforePos);
  const depth = $pos.depth - 1;

  if (depth < 1) {
    return undefined;
  }

  const parentBeforePos = $pos.before(depth);
  // ...rest of function
};

BlockNote version

0.47.1

Environment

All browsers (Chrome, Firefox, Safari). Reproducible in both browser and jsdom (vitest).

Additional context

Related to #2452 and #2453. PR #2126 fixed forward-delete for most cases but introduced this regression for the last-block edge case.

Contribution

  • I'd be interested in contributing a fix for this issue

Sponsor

  • I'm a sponsor and would appreciate if you could look into this sooner than later 💖

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions