ianstormtaylor/slate · critical · Error

[Slate] initialValue is invalid! Expected a list of elements

Error message

[Slate] initialValue is invalid! Expected a list of elements but got: ${Scrubber.stringify(
          initialValue
        )}

What it means

The <Slate> React component validates on first mount that initialValue is a valid Node[] (list of elements). If it is not (wrong shape, undefined, a single node instead of an array, malformed JSON), it throws immediately so the editor never mounts with a broken document.

Source

Thrown at packages/slate-react/src/components/slate.tsx:40

  children: React.ReactNode
  onChange?: (value: Descendant[]) => void
  onSelectionChange?: (selection: Selection) => void
  onValueChange?: (value: Descendant[]) => void
}) => {
  const {
    editor,
    children,
    onChange,
    onSelectionChange,
    onValueChange,
    initialValue,
    ...rest
  } = props

  // Run once on first mount, but before `useEffect` or render
  React.useState(() => {
    if (!Node.isNodeList(initialValue)) {
      throw new Error(
        `[Slate] initialValue is invalid! Expected a list of elements but got: ${Scrubber.stringify(
          initialValue
        )}`
      )
    }

    if (!Editor.isEditor(editor)) {
      throw new Error(
        `[Slate] editor is invalid! You passed: ${Scrubber.stringify(editor)}`
      )
    }

    editor.children = initialValue
    Object.assign(editor, rest)
  })

  const { selectorContext, onChange: handleSelectorChange } =
    useSelectorContext()

View on GitHub (pinned to 72a37c701e)

Solutions

  1. Pass a valid default like initialValue=[{ type: 'paragraph', children: [{ text: '' }] }] and swap in fetched content later via editor.children assignment
  2. Validate/normalize persisted JSON with Node.isNodeList (or a schema normalizer) before rendering <Slate>
  3. Convert foreign formats (HTML/Markdown) to a Slate node tree before mounting

Example fix

// before
<Slate editor={editor} initialValue={savedDoc}> // savedDoc may be undefined/corrupt

// after
const initialValue = Node.isNodeList(savedDoc)
  ? savedDoc
  : [{ type: 'paragraph', children: [{ text: '' }] }]
<Slate editor={editor} initialValue={initialValue}>
Defensive patterns

Strategy: validation

Validate before calling

const safeValue = Node.isNodeList(initialValue)
  ? initialValue
  : [{ type: 'paragraph', children: [{ text: '' }] }]
<Slate editor={editor} initialValue={safeValue}>

Type guard

const isValidValue = (v: unknown): v is Descendant[] => Node.isNodeList(v)

Try / catch

try { render(<Slate editor={e} initialValue={v}/>) } catch (err) { if (/initialValue is invalid/.test(err.message)) fallbackToDefault() else throw err }

Prevention

When it happens

Trigger: <Slate editor={editor} initialValue={initialValue}> where initialValue is not an array of valid Slate nodes — e.g. undefined, an object, an array of strings, or a single element instead of a list.

Common situations: Fetching initial content asynchronously and passing it before the fetch resolves (undefined); restoring from localStorage/JSON with corrupted or old-format data; migration from another editor format (HTML string, ProseMirror doc) without converting to Slate nodes.

Related errors


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