toeverything/AFFiNE · error · BlockSuiteError
TransformerError
TransformerError
Error message
Blob ${blobId} not found in assets manager What it means
AssetsManager.writeToBlob(blobId) looks the id up in its in-memory _assetsMap and throws TransformerError if it is absent. The map is populated only by readFromBlob, so every blob must first be loaded from the source blob storage before it can be written to the target. Note that readFromBlob silently skips missing blobs (it console.errors 'Blob ... not found in blob manager' and returns), so a missing source blob turns into this throw later at write time.
Solutions
- Always await assets.readFromBlob(blobId) before assets.writeToBlob(blobId).
- Check assets.getAssets().has(blobId) before writing and skip (or report) ids that failed to load.
- Ensure the source blob storage actually contains the referenced blobs (upload or copy them first).
Example fix
// before
await assets.writeToBlob(blobId);
// after
await assets.readFromBlob(blobId);
if (assets.getAssets().has(blobId)) {
await assets.writeToBlob(blobId);
} else {
console.warn(`skipping missing blob ${blobId}`);
} Defensive patterns
Strategy: validation
Validate before calling
for (const blobId of blobIds) {
await assets.readFromBlob(blobId);
if (!assets.getAssets().has(blobId)) {
console.warn(`blob ${blobId} missing in source storage; skipping`);
continue;
}
await assets.writeToBlob(blobId);
} Type guard
const isLoadedAsset = (assets: AssetsManager, blobId: string): boolean => assets.getAssets().has(blobId);
Try / catch
try {
await assets.writeToBlob(blobId);
} catch (e) {
if (e instanceof BlockSuiteError && e.message.includes('not found in assets manager')) {
await assets.readFromBlob(blobId); // load, then retry once
await assets.writeToBlob(blobId);
} else throw e;
} Prevention
- Always pair writeToBlob with a preceding awaited readFromBlob for the same id.
- Remember readFromBlob fails silently for missing blobs — check getAssets().has() afterwards.
- Verify referenced blob ids exist in the source storage before starting an import.
When it happens
Trigger: Calling assets.writeToBlob(id) before awaiting assets.readFromBlob(id); the snapshot references a blobId that no longer exists in the source blob storage (readFromBlob skipped it); blobs deleted between export and import.
Common situations: Importing snapshots whose assets were stripped or never uploaded; cross-workspace import where the source storage lacks the referenced blob ids; blob GC running before the copy completes.
Related errors
- ErrorCode.TransformerError
- No root node found in the tree
- 1
- TransformerError
- A config file path is required
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/ca57564947787545.
Report an issue: GitHub.
Appendix: 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 b4c8548c09)