What’s broken?
Pressing Enter inside a table cell can crash the editor with:
TransformError: Cannot join tableCell onto blockContainer
Once it throws, the editor is in a broken state and the document cannot be edited further.
The table-specific Enter handler (added in #2685, "Enter moves selection to cell below in tables") only handles the case where there is a cell below the current one. In several edge cases it returns false and falls through to the default splitBlock handler. That handler resolves the nearest block container of a cell to the outer blockContainer that wraps the whole table (whose content — the table — is non-empty), so it proceeds to call tr.split(pos, 2, ...) at a position deep inside the cell. Splitting a tableCell this way is invalid and ProseMirror throws Cannot join tableCell onto blockContainer.
Edge cases that trigger the fallback (and therefore crash):
- Cursor in a cell on the last row (no cell below).
- A non-empty text selection inside a cell on the last row.
- A multi-cell selection (
CellSelection) — here the selection head resolves to a tableRow, so the handler's tableParagraph guard is bypassed entirely.
What did you expect to happen?
Pressing Enter inside a table should never crash the editor or corrupt the table structure. When there is no cell below (e.g. the last row) or the selection spans multiple cells, Enter should either move appropriately within the table or be a no-op — but it must not fall through to splitBlock and split the table cell.
Steps to reproduce
Reproducible on the official demo (no app-specific code needed):
👉 https://www.blocknotejs.org/demo#pwls9
- Open the demo above (it contains a table).
- Click inside a cell in the last row of the table.
- Press Enter.
- The editor crashes (see console) with
TransformError: Cannot join tableCell onto blockContainer.
It also reproduces by selecting text within a last-row cell and pressing Enter, or by selecting across multiple cells and pressing Enter.
Stack trace (minified in prod, structure shown):
TransformError: Cannot join tableCell onto blockContainer
at new TransformError (prosemirror-transform)
at Transaction.step (prosemirror-transform)
at split (prosemirror-transform)
at Transaction.split (prosemirror-transform)
at splitBlockTr (packages/core/src/api/blockManipulation/commands/splitBlock/splitBlock.ts:55) // tr.split(posInBlock, 2, types)
at splitBlockCommand (.../splitBlock.ts:22)
at KeyboardShortcutsExtension Enter handler (.../KeyboardShortcuts/KeyboardShortcutsExtension.ts:918)
// chain().deleteSelection().command(splitBlockCommand(...)).run() — reached because the
// table's Enter handler returned false and fell through to the default splitBlock
BlockNote version
@blocknote/core 0.51.2 and 0.51.3 (latest). The regression was introduced in 0.50.0 by #2685.
Environment
Reproducible on the official demo site (any modern browser); framework-independent (core bug).
Additional context
Likely caused by #2685 ("feat: Enter moves selection to cell below in tables (BLO-1006)"), which implemented the Enter-in-table behavior requested in #2409. Its Enter handler in packages/core/src/blocks/Table/TableExtension.ts returns false for the edge cases above, letting the default splitBlock handler split the table cell and throw.
I searched open/closed issues and PRs (and double-checked via an independent search) and found no existing report or fix for this specific crash. #2409 (closed) is the original feature request and does not mention the crash.
Contribution
What’s broken?
Pressing Enter inside a table cell can crash the editor with:
Once it throws, the editor is in a broken state and the document cannot be edited further.
The table-specific Enter handler (added in #2685, "Enter moves selection to cell below in tables") only handles the case where there is a cell below the current one. In several edge cases it returns
falseand falls through to the defaultsplitBlockhandler. That handler resolves the nearest block container of a cell to the outerblockContainerthat wraps the whole table (whose content — the table — is non-empty), so it proceeds to calltr.split(pos, 2, ...)at a position deep inside the cell. Splitting atableCellthis way is invalid and ProseMirror throwsCannot join tableCell onto blockContainer.Edge cases that trigger the fallback (and therefore crash):
CellSelection) — here the selection head resolves to atableRow, so the handler'stableParagraphguard is bypassed entirely.What did you expect to happen?
Pressing Enter inside a table should never crash the editor or corrupt the table structure. When there is no cell below (e.g. the last row) or the selection spans multiple cells, Enter should either move appropriately within the table or be a no-op — but it must not fall through to
splitBlockand split the table cell.Steps to reproduce
Reproducible on the official demo (no app-specific code needed):
👉 https://www.blocknotejs.org/demo#pwls9
TransformError: Cannot join tableCell onto blockContainer.It also reproduces by selecting text within a last-row cell and pressing Enter, or by selecting across multiple cells and pressing Enter.
Stack trace (minified in prod, structure shown):
BlockNote version
@blocknote/core0.51.2 and 0.51.3 (latest). The regression was introduced in 0.50.0 by #2685.Environment
Reproducible on the official demo site (any modern browser); framework-independent (core bug).
Additional context
Likely caused by #2685 ("feat: Enter moves selection to cell below in tables (BLO-1006)"), which implemented the Enter-in-table behavior requested in #2409. Its Enter handler in
packages/core/src/blocks/Table/TableExtension.tsreturnsfalsefor the edge cases above, letting the defaultsplitBlockhandler split the table cell and throw.I searched open/closed issues and PRs (and double-checked via an independent search) and found no existing report or fix for this specific crash. #2409 (closed) is the original feature request and does not mention the crash.
Contribution