toeverything/AFFiNE · error · DocNotFound
doc_not_found
doc_not_found
Error message
Doc ${docId} under Space ${spaceId} not found. What it means
Thrown by WorkspacesController.getDocBinaryOrThrow when DocReader.getDoc(workspaceId, docId) resolves null — after permission checks passed, the server could not load any binary/update data for that doc id in that workspace. It is the not-found signal of the doc storage layer (snapshots/updates plus blob backing).
Solutions
- Verify the doc exists via doc meta / workspace doc list before fetching its binary
- Check the workspaceId/docId pair — the same guid in the wrong space is not found
- If storage was wiped or migrated, restore snapshots/updates or re-create the doc
- Server-side, trace DocReader.getDoc dependencies (snapshot + update models, storage) to see which layer returns null for the pair
Defensive patterns
Strategy: try-catch
Validate before calling
// confirm the doc exists before fetching its binary
const meta = await getDocMeta(wsId, docId);
if (!meta) {
handleDocGone(docId);
return;
} Type guard
function isDocNotFound(e: unknown): e is { code: 'doc_not_found'; docId: string; spaceId: string } {
return typeof e === 'object' && e !== null && (e as any).code === 'doc_not_found';
} Try / catch
try {
return await getDocBinary(wsId, docId);
} catch (e) {
if (isDocNotFound(e)) {
removeDocFromLocalCache(e.docId); // stale id — stop retrying
return null;
}
throw e;
} Prevention
- Sync doc lists before dereferencing doc ids from old links or caches
- Treat doc deletion events as a signal to invalidate stored doc ids
- Never guess doc guids or copy them across workspaces
- Back up snapshots/updates before migrating storage so reads don't return null
When it happens
Trigger: Internal doc-binary fetches (getDocBinaryOrThrow callers) where the doc was deleted, its snapshots/updates were never written or were garbage-collected, or the guid simply does not exist in that workspace.
Common situations: Client holding a stale docId after the doc was deleted in another session; workspace data pruned or migrated without snapshots; copy-pasted wrong guid; snapshot/update storage (S3, database) misconfigured so reads return null; doc created but its first sync never completed.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of toeverything/AFFiNE@2af30773ae (2026-08-18).
Data as JSON: /api/errors/b3f7b50c055db3d3.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/core/workspaces/controller.ts:90
}
}
private async getPublishModeHeader(workspaceId: string, docId: string) {
const docMeta = await this.models.doc.getMeta(workspaceId, docId, {
select: {
mode: true,
},
});
return docMeta?.mode === PublicDocMode.Edgeless
? DocMode.edgeless
: DocMode.page;
}
private async getDocBinaryOrThrow(workspaceId: string, docId: string) {
const binResponse = await this.docReader.getDoc(workspaceId, docId);
if (!binResponse) {
throw new DocNotFound({
spaceId: workspaceId,
docId,
});
}
return binResponse;
}
@Public()
@Get('/:id/blob-manifest/v1')
async blobManifestV1(
@CurrentUser() user: CurrentUser | undefined,
@Param('id') workspaceId: string,
@Query('sourceType') sourceType: string,
@Query('docId') docId: string,
@Query('timestampMs') timestampMs: string | undefined,
@Res() res: Response
) {View on GitHub (pinned to 2af30773ae)