toeverything/AFFiNE · error · BlockSuiteError

TransformerError

TransformerError

Error message

Blob ${blobId} not found in assets manager

What it means

Thrown by AssetsManager.writeToBlob() when the requested blobId is not present in the internal _assetsMap. The assets manager is a staging area for blobs during snapshot import/export — blobs must first be read or added via readFromBlob() before they can be written. This error indicates a write was attempted for an asset that was never loaded into the manager.

Source

Thrown at blocksuite/framework/store/src/transformer/assets.ts:97

      this._assetsMap.set(blobId, blob);
      return;
    }
    // Guess the file type from the buffer
    const buffer = await blob.arrayBuffer();
    const FileType = await import('file-type');
    const fileType = await FileType.fileTypeFromBuffer(buffer);
    if (fileType) {
      const file = new File([blob], '', { type: fileType.mime });
      this._assetsMap.set(blobId, file);
      return;
    }
    this._assetsMap.set(blobId, blob);
  }

  async writeToBlob(blobId: string) {
    const blob = this._assetsMap.get(blobId);
    if (!blob) {
      throw new BlockSuiteError(
        ErrorCode.TransformerError,
        `Blob ${blobId} not found in assets manager`
      );
    }

    await this._blob.set(blobId, blob);
  }
}

View on GitHub (pinned to 26c515e050)

Solutions

  1. Ensure readFromBlob(blobId) is awaited before calling writeToBlob(blobId) for the same ID.
  2. Verify the blobId actually exists in the underlying blob store (BlobCRUD.get) before attempting to read/write.
  3. Avoid calling assetsManager.cleanup() between read and write operations.
  4. Check snapshot data for stale or invalid blob references and handle missing blobs gracefully.

Example fix

// before
await assetsManager.writeToBlob(blobId); // never read -> throws

// after
await assetsManager.readFromBlob(blobId);
await assetsManager.writeToBlob(blobId);
Defensive patterns

Strategy: validation

Validate before calling

if (!assetsManager.getAssets().has(blobId)) {
  await assetsManager.readFromBlob(blobId);
}
await assetsManager.writeToBlob(blobId);

Type guard

const isAssetLoaded = (assetsManager: AssetsManager, blobId: string): boolean =>
  assetsManager.getAssets().has(blobId);

Try / catch

try {
  await assetsManager.writeToBlob(blobId);
} catch (e) {
  if (e instanceof BlockSuiteError && e.code === ErrorCode.TransformerError) {
    // attempt to read the blob first, then retry
    await assetsManager.readFromBlob(blobId);
    await assetsManager.writeToBlob(blobId);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling assetsManager.writeToBlob(blobId) without first calling readFromBlob(blobId) or otherwise populating _assetsMap with that blobId. Triggered during snapshot-to-doc import when a block references a blob that wasn't fetched from the blob store.

Common situations: Importing a snapshot whose blocks reference blob IDs that don't exist in the source workspace's blob storage. Calling writeToBlob before the async readFromBlob has completed. Assets manager cleanup() was called between read and write, clearing the map.

Related errors


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