toeverything/AFFiNE · error · BlockSuiteError

EdgelessExportError

EdgelessExportError

Error message

Unable to export content to canvas

What it means

YjsDBAdapter builds its table map exactly once, in the constructor, from the schema object passed in — creating one Yjs doc per declared table. table(name) looks up that prebuilt map and throws the bare 'Table not found' when the name was never declared, because there is no Yjs doc backing an undeclared table.

Solutions

  1. Declare the table in the DB schema builder passed to YjsDBAdapter so a doc is created for it
  2. Fix the name at the call site; centralize table names as constants shared with the schema definition
  3. For dynamic access, check the public tables map first: db.tables.has(name)

Example fix

// before
const t = db.table('usres'); // typo -> Table not found

// after
const TABLES = { users: usersSchema, docs: docsSchema } as const; // single source of truth
const db = new YjsDBAdapter(TABLES, docProvider);
const t = db.table('users');
Defensive patterns

Strategy: validation

Validate before calling

function getTable(db: YjsDBAdapter, name: string) {
  if (!db.tables.has(name)) {
    throw new Error(`Table '${name}' not declared in schema. Declared: ${[...db.tables.keys()].join(', ')}`);
  }
  return db.table(name);
}

Type guard

null

Prevention

When it happens

Trigger: Calling db.table('usres') with a typo; accessing a table present in a different or newer schema than the one the adapter was constructed with; a schema migration renamed the table while callers kept the old name; constructing the adapter from an empty/partial schema object.

Common situations: Version skew between the schema definition and consuming code; table names assembled dynamically from strings that drift from declarations; adapter instantiated before the schema module populates its definitions.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/84348b057f31d0f0. Report an issue: GitHub.

Appendix: source

Thrown at blocksuite/affine/blocks/surface/src/extensions/export-manager/export-manager.ts:112

    await Promise.all(promises);
  };

  get doc(): Store {
    return this.std.store;
  }

  get editorHost(): EditorHost {
    return this.std.host;
  }

  constructor(readonly std: BlockStdScope) {}

  private _checkCanContinueToCanvas(pathName: string, editorMode: boolean) {
    if (
      location.pathname !== pathName ||
      isInsidePageEditor(this.editorHost) !== editorMode
    ) {
      throw new BlockSuiteError(
        ErrorCode.EdgelessExportError,
        'Unable to export content to canvas'
      );
    }
  }

  private async _checkReady() {
    const pathname = location.pathname;
    const editorMode = isInsidePageEditor(this.editorHost);

    const promise = new Promise((resolve, reject) => {
      let count = 0;
      const checkReactRender = setInterval(() => {
        try {
          this._checkCanContinueToCanvas(pathname, editorMode);
        } catch (e) {
          clearInterval(checkReactRender);
          reject(e);

View on GitHub (pinned to b4c8548c09)