toeverything/AFFiNE · critical · BlockSuiteError

ErrorCode.NoRootModelError

ErrorCode.NoRootModelError

Error message

This doc is missing root block. Please initialize the default block structure before connecting the editor to DOM.

What it means

FATAL error (`NoRootModelError`, code >= 10000) thrown by `EditorHost.connectedCallback` in lit-host.ts when `this.store.root` is falsy at the moment the host connects to the DOM. BlockSuite requires the doc to have an initialized root block before the editor mounts; otherwise it cannot render anything and aborts. Because it is fatal, the framework's `handleError` rethrows it wrapped.

Source

Thrown at blocksuite/framework/std/src/view/lit-host.ts:131

View on GitHub (pinned to 26c515e050)

Solutions

  1. Initialize the root block before mounting: `doc.reset()` or add a default root block via the doc API.
  2. Await the doc's loaded signal/promise (`await doc.loaded` / `store.awarenessStore` ready) before connecting `<editor-host>`.
  3. Verify the snapshot import produced a non-null `store.root` before mounting.

Example fix

// before: mounting an uninitialized doc
const doc = collection.createDoc();
document.body.appendChild(host); // store.root is null -> fatal

// after: initialize the root block first, then mount
const doc = collection.createDoc();
doc.load();
doc.reset(); // creates the default root block structure
document.body.appendChild(host);
Defensive patterns

Strategy: validation

Validate before calling

// ensure the doc has a root before mounting the editor host
function docHasRoot(store: Store): boolean {
  return !!store.root;
}

if (docHasRoot(store)) document.body.appendChild(host);
else throw new Error('Initialize the root block before mounting the editor.');

Type guard

function storeHasRoot(store: Store): store is Store & { root: BlockModel } {
  return !!store.root;
}

Try / catch

// No recovery: this is fatal. Validate before mount instead.
if (!store.root) {
  throw new Error('Cannot mount editor without a root block');
}
try {
  document.body.appendChild(host);
} catch (e) {
  if (e instanceof Error && /missing root block/i.test(e.message)) {
    console.error('Editor mount failed: doc has no root block');
  }
  throw e;
}

Prevention

When it happens

Trigger: Appending `<editor-host>` to the DOM before the doc has a root block — e.g. creating a `DocCollection`/`Store` and immediately mounting without calling `doc.reset()` / `aw Rap` initialization, or mounting before an async `loadStep`/`doc.load(...)` has populated the root.

Common situations: Empty new doc not given a default root block; importing a snapshot whose root failed to deserialize; awaiting `doc.loaded` incorrectly; SSR pass with an uninitialized doc.

Related errors


AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12). Data as JSON: /api/errors/a166407e7bf07bfc. Report an issue: GitHub.