toeverything/AFFiNE · error · DocNotFound

doc_not_found

doc_not_found

Error message

Doc ${docId} under Space ${spaceId} not found.

What it means

Thrown by getDocBinaryOrThrow when DocReader.getDoc returns a falsy binary response for the requested workspace/doc. It means the doc snapshot/updater has no binary for that id: the doc does not exist in this workspace or its data has not been replicated yet.

Source

Thrown at packages/backend/server/src/core/workspaces/controller.ts:88

    }
  }

  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;
  }

  // get workspace blob
  //
  // NOTE: because graphql can't represent a File, so we have to use REST API to get blob
  @Public()
  @Get('/:id/blobs/:name')
  @CallMetric('controllers', 'workspace_get_blob')
  async blob(
    @CurrentUser() user: CurrentUser | undefined,
    @Param('id') workspaceId: string,
    @Param('name') name: string,

View on GitHub (pinned to 26c515e050)

Solutions

  1. Confirm the docId and workspaceId are correct and that the doc exists in that workspace.
  2. If recently created/deleted, retry after replication settles.
  3. Check DocReader/snapshot storage health if many docs 404 unexpectedly.
  4. Clean up stale references/bookmarks pointing at removed docs.

Example fix

// before
const bin = await docReader.getDoc(ws, docId)
return bin
// after
const bin = await docReader.getDoc(ws, docId)
if (!bin) throw new NotFound('doc not found in this workspace')
return bin
Defensive patterns

Strategy: validation

Validate before calling

const exists = await models.doc.exists(workspaceId, docId)
if (!exists) return notFoundPage(docId)

Try / catch

try { await loadDoc(ws, docId) } catch (e) {
  if (e.code === 'doc_not_found') showEmptyState()
  else throw e
}

Prevention

When it happens

Trigger: Calling the doc-fetch endpoint for a docId that was never created, was deleted, belongs to a different workspace, or whose binary is not yet available on this node (replication lag).

Common situations: Stale bookmark/URL to a deleted doc; cross-workspace id collision; a freshly created doc whose binary has not synced; pointing at the wrong workspace id.

Related errors


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