docs/solutions/runtime-errors/2026-05-23-slate-v2-rootless-explicit-selections-must-not-inherit-sibling-root.md
After focusing a non-main root, clicking a later paragraph in the main root could
store the main path under the previous root. A header-root marks read then tried
to resolve [1,0] inside the header tree and crashed.
Cannot find a descendant at path [1,0].roots:header
set_selection commit.state.marks.get() in
runtime-root-engine.ts.useSlateActiveRoot. That removed a selector rerender loop, but
did not change how rootless explicit selection targets were rooted.Keep current-selection-root fallback for implicit edits, but do not let it root
an explicit rootless location on the base runtime. Rootless explicit locations
on the runtime mean main; root-bound views still stamp their view root through
the active operation root.
const getLocationMutationRoot = (
editor: Editor,
location: Location
): string | undefined =>
getExplicitLocationRoot(location) ??
getActiveMutationRoot(editor) ??
MAIN_ROOT_KEY
Also avoid wrapping a plain editor.update in the current selection root. The
per-mutation root resolver already handles implicit operations that should
follow the current selection.
There are two different cases:
tx.text.insert('x') should follow the current selection
root.tx.selection.set({ path: [1, 0], offset: 0 })
on the base runtime should target main.The bug came from collapsing both cases into "current selection root". Splitting them lets main-root DOM selection imports replace a previous header selection instead of storing a main path under header ownership.