ianstormtaylor/slate · error · Error

Cannot set the "then" property of the selection to a…

Error message

Cannot set the "then" property of the selection to a function

What it means

Slate refuses to set a 'then' property on the selection when the value is a function, because a thenable selection would be treated as a Promise-like object. Returning such a selection from an async function would auto-await it and cause surprising behavior, so Slate guards against it explicitly.

Solutions

  1. Strip any 'then' key from selection properties before calling setSelection
  2. Validate that no property value in the operation is a function before applying remote ops
  3. If you need a custom selection key, rename it away from 'then'

Example fix

// before
Transforms.setSelection(editor, propsWithThen as any)

// after
delete propsWithThen['then']
Transforms.setSelection(editor, propsWithThen as Partial<Range>)
Defensive patterns

Strategy: validation

Validate before calling

if ('then' in props && typeof props['then'] === 'function') {
  throw new Error('then must not be a function on selection')
}
const { then, ...rest } = props as any
Transforms.setSelection(editor, rest)

Type guard

const hasFunctionThen = (o: object): boolean =>
  'then' in o && typeof (o as any).then === 'function'

Prevention

When it happens

Trigger: Transforms.setSelection(editor, { then: () => {} }) or applying a set_selection op whose properties include then: function; usually from deserialized/untrusted data where 'then' is a function value.

Common situations: Applying remote or localStorage-persisted operations that were not sanitized; JSON payloads where a key named 'then' resolved to a function via eval-like revival; prototype-pollution attempts.

Related errors


AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27). Data as JSON: /api/errors/4fc07a96e9a4f781. Report an issue: GitHub.

Appendix: source

Thrown at packages/slate/src/interfaces/transforms/general.ts:328

        }

        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!`
            )
          }

          const value = newProperties[<keyof Range>key]

          // Make sure we're not setting `then` to a function, since this will
          // cause the selection to be treated as a Promise-like object, which
          // can cause unexpected behaviour when returning the selection from
          // async functions.
          if (key === 'then' && typeof value === 'function') {
            throw new Error(
              'Cannot set the "then" property of the selection to a function'
            )
          }

          if (value == null) {
            if (key === 'anchor' || key === 'focus') {
              throw new Error(`Cannot remove the "${key}" selection property`)
            }

            delete selection[<keyof Range>key]
          } else {
            selection[<keyof Range>key] = value
          }
        }

        editor.selection = selection

        break

View on GitHub (pinned to 72a37c701e)