Skip to content

Block doesn't have id during Editor.mount #2682

@RobinClowers

Description

@RobinClowers

What’s broken?

Summary: After upgrading from 0.46.1 to 0.49.0, an intermittent "Block doesn't have id" error fires during initial editor mount when navigating between collaborative pages.

The thrown editor's state has been observed to contain content from a different room/Y.Doc than the one the component was rendering.

Environment:

  • @blocknote/{core,react,mantine,xl-pdf-exporter,server-util}: 0.49.0
  • React 19, Next.js 16 (Turbopack dev), --turbo mode
  • TipTap core 3.15.x, Y.js 13.6.30
  • Collaboration via @hocuspocus/provider 3.4.4

Stack:

kt (internal.ts:108) — throws "Block doesn't have id"
  ← addNodeView in createSpec.ts:191 (createBlockSpec custom block)
  ← TipTap nodeview (ExtensionManager.ts:227)
  ← prosemirror NodeViewDesc.create
  ← ViewTreeUpdater.addNode → iterDeco → updateChildren (×N)
  ← docViewDesc → new EditorView
  ← Editor.createView → Editor.mount → BlockNoteEditor.mount
  ← BlockNoteView.tsx:295 (ref attach)
  ← commitAttachRef → safelyAttachRef
  ← reappearLayoutEffects   ← React 19 Activity / Offscreen reappear path

Smoking gun: patching Editor.prototype.mount to log editor.state.doc.toJSON() at every mount captured an editor instance bound to the URL of new page B whose state contained custom blocks (type: "task", task_id: "") from page A's content. Page A and page B are different Hocuspocus rooms with independent .yjs files on disk (verified). The leak happens in-memory, on the client.

Did NOT fix it: adding key={roomId} and key={doc.guid} on the wrapping context-provider components above BlockNoteView. That suggests the leak is below the component-key boundary — most likely tied to the editor instance returned by useCreateBlockNote not being torn down before its BlockNoteView ref is reattached during a reappearLayoutEffects traversal.

What did you expect to happen?

No error

Steps to reproduce

  1. App with multiple collaborative pages (each is its own Y.Doc room) backed by Hocuspocus.
  2. Open page A (page with custom blocks created via createBlockSpec).
  3. Click "add new page" — UI navigates to a fresh page B, server-seeds B's Y.Doc with template binary via Hocuspocus.
  4. Click "apply template" — B's is_empty flag flips, parent re-renders to mount the BlockNote editor for the first time.
  5. ~10% of the time, the editor mount throws.

BlockNote version

0.46.2

Environment

Chrome 147, macos

Additional context

I bisected and found that https://github.com/TypeCellOS/BlockNote/releases/tag/v0.46.2 introduced the issue. Best leads from a quick scan:

Contribution

  • I'd be interested in contributing a fix for this issue

Sponsor

  • I'm a sponsor and would appreciate if you could look into this sooner than later 💖

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageIssue has not yet been reviewed or classified by maintainers.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions