ianstormtaylor/slate · error · Error
Cannot apply an incomplete "set_selection" operation propert
Error message
Cannot apply an incomplete "set_selection" operation properties ${Scrubber.stringify(
newProperties
)} when there is no current selection. What it means
Thrown by Editor.transform when applying a 'set_selection' operation with partial properties (missing anchor or focus) while editor.selection is null. Since there is no existing selection to merge the partial properties into, Slate cannot construct a valid new selection. It indicates the caller tried to update a selection that does not exist yet.
Source
Thrown at packages/slate/src/interfaces/transforms/general.ts:301
}
return newNode
})
break
}
case 'set_selection': {
const { newProperties } = op
if (newProperties == null) {
editor.selection = null
break
}
if (editor.selection == null) {
if (!(newProperties.anchor && newProperties.focus)) {
throw new Error(
`Cannot apply an incomplete "set_selection" operation properties ${Scrubber.stringify(
newProperties
)} when there is no current selection.`
)
}
editor.selection = { ...(newProperties as Range) }
break
}
const selection = { ...editor.selection }
for (const key in newProperties) {
if (NON_SETTABLE_SELECTION_PROPERTIES.includes(key)) {
throw new Error(
`Cannot set the "${key}" property of the selection!`
)
}View on GitHub (pinned to 72a37c701e)
Solutions
- Check editor.selection != null before calling Transforms.setSelection with partial properties, or pass a full Range {anchor, focus}
- If selection is null, use Transforms.select(editor, range) with a complete Range/Point/Path instead
- When replaying remote operations, skip or re-order set_selection ops so a selection exists first
Example fix
// before
Transforms.setSelection(editor, { focus: { path: [0,0], offset: 2 } }) // selection is null
// after
if (editor.selection) {
Transforms.setSelection(editor, { focus: { path: [0,0], offset: 2 } })
} else {
Transforms.select(editor, { anchor: { path: [0,0], offset: 0 }, focus: { path: [0,0], offset: 2 } })
} Defensive patterns
Strategy: validation
Validate before calling
const canSetSelection = editor.selection != null || (props.anchor != null && props.focus != null)
if (!canSetSelection) throw new Error('Need full anchor+focus when selection is null')
if (editor.selection != null) Transforms.setSelection(editor, props)
else Transforms.select(editor, props as Range) Type guard
const isFullRange = (r: unknown): r is Range => Range.isRange(r) || (!!r && typeof r === 'object' && 'anchor' in r && 'focus' in r)
Prevention
- Always provide both anchor and focus when editor.selection may be null
- Check editor.selection before partial setSelection calls
- When replaying ops, ensure a set_selection establishing a selection comes before partial updates
When it happens
Trigger: Calling Transforms.setSelection(editor, {focus: ...}) or Editor.applySelection/Transforms.transform with partial range properties when editor.selection === null; replaying an operation log where a set_selection op assumes a prior selection existed.
Common situations: After deselect() or on a fresh editor with no selection, code applies remote/collaborative ops or calls setSelection with only anchor or only focus; desynced selection state in Yjs/ot-based collaboration.
Related errors
- Cannot remove the "${key}" selection property
- When setting the selection and the current selection is \`nu
- Cannot resolve a Slate range from a DOM event: ${event}
- Cannot resolve a DOM point from Slate point: ${Scrubber.stri
- Cannot resolve a Slate point from DOM point: ${domPoint}
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/12fd72db88809212.
Report an issue: GitHub.