toeverything/AFFiNE · error · BlockSuiteError
DatabaseBlockError
DatabaseBlockError
Error message
View ${viewId} not found What it means
Thrown by DataViewRootUILogic.createDataViewUILogic (blocksuite/affine/data-view/src/core/data-view.ts:64-71) when viewManager.viewGet(viewId) returns undefined. The data-view widget builds a per-view UI logic for every id in dataSource.viewDataList$; if the view manager cannot resolve an id to a view meta (renderer, name), database-block rendering aborts with this DatabaseBlockError. It almost always means a dangling view id: the id list and the actual view storage are out of sync.
Solutions
- Check dataSource.viewManager.viewGet(viewId) before rendering and skip/prune the stale id instead of constructing the UI logic
- Delete the stale entry from the block's view list (viewDelete or equivalent) so viewDataList$ and the view manager stay in sync
- When restoring old snapshots, migrate first: drop view entries whose id no longer resolves, or rebuild a default view
- Wrap mount/render in try-catch for BlockSuiteError with code DatabaseBlockError and fall back to the first resolvable view
Example fix
// before
const logic = this.createDataViewUILogic(viewData.id); // throws 'View xxx not found'
// after
const view = this.viewManager.viewGet(viewData.id);
if (!view) {
this.viewManager.viewDelete(viewData.id); // prune the dangling id
return null;
} Defensive patterns
Strategy: validation
Validate before calling
const isViewIdResolvable = (dataSource: DataSource, viewId: string): boolean => !!dataSource.viewManager.viewGet(viewId); // prune before rendering const validViewData = dataSource.viewDataList$.value.filter(v => isViewIdResolvable(dataSource, v.id) );
Type guard
function isResolvedView(view: SingleView | undefined): view is SingleView {
return view !== undefined;
} Try / catch
try {
const logic = this.createDataViewUILogic(viewId);
} catch (e) {
if (e instanceof BlockSuiteError && e.code === BlockSuiteError.ErrorCode.DatabaseBlockError) {
// stale view id: remove it from the view list and re-render, do not crash the editor
this.viewManager.viewDelete(viewId);
return;
}
throw e;
} Prevention
- Always delete views through the view manager API so id lists and storage update atomically
- When loading/restoring snapshots, drop view entries whose ids do not resolve before mounting the data-view
- Never construct view ids by string manipulation; use ids from viewDataList$
When it happens
Trigger: A view is deleted while the views$ computed is mid-update (reactive race), so viewDataList$ still holds a removed id; restoring a database-block snapshot whose views array references a view id that no longer exists; calling viewManager.viewGet / mounting the data-view with a stale or hand-crafted id from untrusted JSON.
Common situations: Rapid view deletion during a reactive re-render; corrupted or hand-edited database block JSON; collaborative editing where a remote peer deletes a view the local client is rendering; block migrations that regenerate view ids without pruning references.
Related errors
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/b0633aacc2b976b8.
Report an issue: GitHub.
Appendix: source
Thrown at blocksuite/affine/data-view/src/core/data-view.ts:67
data: {
view: SingleView;
rowId: string;
}
) => Promise<void>;
};
};
export class DataViewRootUILogic {
private get dataSource() {
return this.config.dataSource;
}
private get viewManager() {
return this.dataSource.viewManager;
}
private createDataViewUILogic(viewId: string): DataViewUILogicBase {
const view = this.viewManager.viewGet(viewId);
if (!view) {
throw new BlockSuiteError(
BlockSuiteError.ErrorCode.DatabaseBlockError,
`View ${viewId} not found`
);
}
const pcLogic = view.meta.renderer.pcLogic;
const mobileLogic = view.meta.renderer.mobileLogic;
const logic = (IS_MOBILE ? mobileLogic : pcLogic) ?? pcLogic;
return new (logic(view))(this, view);
}
private readonly _viewsCache = new Map<
string,
{ mode: string; logic: DataViewUILogicBase }
>();
private readonly views$ = computed(() => {
const viewDataList = this.dataSource.viewDataList$.value;View on GitHub (pinned to b4c8548c09)