ianstormtaylor/slate · error · Error

A HyperscriptRangeRef must be passed as the ref prop of an <

Error message

A HyperscriptRangeRef must be passed as the ref prop of an <anchor /> tag that is used inside an <editor>.

What it means

In slate-hyperscript, a <anchor ref={...}/> tag's ref stores the anchor Point only when it is rendered inside an <editor> element. Calling .range() on a HyperscriptRangeRef throws this error when the anchor Point was never populated — i.e., the <anchor/> tag was used outside an <editor> or the ref was never attached to an <anchor/> tag at all. The range() method requires both anchor and focus to build a Range.

Source

Thrown at packages/slate-hyperscript/src/refs.ts:38

    return { path, offset }
  }
}

/**
 * Hyperscript range refs can be used to construct arbitrary range using the ref
 * props of <anchor /> and <focus /> tags.
 */

export class HyperscriptRangeRef {
  anchor?: Point
  focus?: Point

  range(): Range {
    const { anchor, focus } = this

    if (anchor == null) {
      throw new Error(
        'A HyperscriptRangeRef must be passed as the ref prop of an <anchor /> tag that is used inside an <editor>.'
      )
    }

    if (focus == null) {
      throw new Error(
        'A HyperscriptRangeRef must be passed as the ref prop of a <focus /> tag that is used inside an <editor>.'
      )
    }

    return { anchor, focus }
  }
}

View on GitHub (pinned to 72a37c701e)

Solutions

  1. Place the <anchor ref={r}/> tag inside an <editor> element
  2. Verify the ref is passed to an <anchor/> tag, not to <focus/> or another tag
  3. Make sure both <anchor ref={r}/> and <focus ref={r}/> (or the same ref) appear inside the same editor before calling range()

Example fix

// before
<fragment>
  <anchor ref={r} />
  <text>a</text>
  <focus ref={r} />
</fragment>
r.current.range() // throws (no anchor)

// after
<editor>
  <anchor ref={r} />
  <text>a</text>
  <focus ref={r} />
</editor>
r.current.range() // works
Defensive patterns

Strategy: validation

Validate before calling

const r = anchorRef.current
if (r?.anchor != null) {
  const range = r.range()
}

Type guard

const hasAnchor = (r) => r != null && r.anchor != null

Prevention

When it happens

Trigger: Using <anchor ref={r}/> inside <fragment>/<element> instead of <editor>; calling r.current.range() before the hyperscript tree containing the anchor is rendered; attaching the ref to a different tag (e.g. <text>) so it never receives an anchor.

Common situations: Test setup where selections are built from fragments; ref variable mixups between anchor and focus; migrating tests that previously used explicit path props on the ref.

Related errors


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