docs/solutions/logic-errors/2026-05-09-slate-v2-adjacent-block-void-delete-must-path-delete-one-target.md
Collapsed backward delete after adjacent block voids treated the target as a range delete. That let one Backspace remove more structure than the nearest void target.
When collapsed delete resolves to an adjacent void or read-only element, delete that element by path and preserve the original caret through a point ref.
The behavior lock is:
// .tmp/slate-v2/packages/slate/test/transforms/delete/voids-false/block-after-multiple-reverse.tsx
export const run = (editor) => {
editor.text.delete({ reverse: true });
};
The fix is in .tmp/slate-v2/packages/slate/src/transforms-text/delete-text.ts:
const targetNonEditable = voids
? undefined
: getHighestNonEditable(editor, target);
if (targetNonEditable && !pathContainsPoint(targetNonEditable[1], at)) {
return {
kind: "path",
path: targetNonEditable[1],
fallbackPoint: at,
initialAt,
};
}
deletePathTarget creates a point ref for fallbackPoint before applying the
remove operation, then sets the selection from the transformed point.
A void/read-only element is an atomic deletion target. Once the collapsed delete target lands inside that atom, the editor should remove that atom, not reinterpret the gesture as a structural range deletion across nearby siblings.
The point ref matters because the caret host usually sits after the removed void. Removing the void shifts that host left, so the fallback point must move with the operation before selection is restored.