toeverything/AFFiNE · error · BlockSuiteError

TransformerError

TransformerError

Error message

Root block not found in doc

What it means

Thrown by Transformer.docToSnapshot() when doc.root is undefined — i.e. the Store (doc) has no root block model. Exporting a doc to a snapshot requires traversing the block tree starting from the root; without a root, the export cannot proceed. Note: the outer docToSnapshot catches this and returns undefined, so callers see undefined rather than the raw error.

Source

Thrown at blocksuite/framework/store/src/transformer/transformer.ts:109

      return snapshot;
    } catch (error) {
      console.error(`Error when transforming block to snapshot:`);
      console.error(error);
      return;
    }
  };

  docToSnapshot = (doc: Store): DocSnapshot | undefined => {
    try {
      this._slots.beforeExport.next({
        type: 'page',
        page: doc,
      });
      const rootModel = doc.root;
      const meta = this._exportDocMeta(doc);
      if (!rootModel) {
        throw new BlockSuiteError(
          ErrorCode.TransformerError,
          'Root block not found in doc'
        );
      }
      const blocks = this.blockToSnapshot(toDraftModel(rootModel));
      if (!blocks) {
        return;
      }
      const docSnapshot: DocSnapshot = {
        type: 'page',
        meta,
        blocks,
      };
      this._slots.afterExport.next({
        type: 'page',
        page: doc,
        snapshot: docSnapshot,
      });

View on GitHub (pinned to 26c515e050)

Solutions

  1. Ensure a root block (e.g. 'affine:page') is added to the doc before calling docToSnapshot.
  2. Check doc.root for undefined before attempting export and handle the empty-doc case.
  3. Call doc.load() after creating the Store to ensure models are initialized from the CRDT state.

Example fix

// before
const doc = docCRUD.create('doc-id');
doc.load();
transformer.docToSnapshot(doc); // no root -> returns undefined

// after
const doc = docCRUD.create('doc-id');
doc.load();
doc.addBlock('affine:page', {});
transformer.docToSnapshot(doc);
Defensive patterns

Strategy: validation

Validate before calling

if (!doc.root) {
  console.warn('Doc has no root block; cannot export to snapshot.');
  return;
}
const snapshot = transformer.docToSnapshot(doc);

Type guard

const hasRootBlock = (doc: Store): boolean => doc.root !== undefined && doc.root !== null;

Try / catch

const snapshot = transformer.docToSnapshot(doc);
if (!snapshot) {
  // docToSnapshot catches internally and returns undefined
  console.warn('Export returned undefined — doc may have no root block.');
}

Prevention

When it happens

Trigger: Calling transformer.docToSnapshot(doc) on a Store that was created but never had a root block added, or whose root block was removed. Also possible if doc.load() wasn't called or the Yjs doc has no root structure.

Common situations: Exporting a newly created doc before adding any blocks. Doc corruption where the root block was deleted. Creating a Store via docCRUD.create(id) but forgetting to add a root block and load the doc before export.

Related errors


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