{"record":{"id":"523e8fba4e58407b","repo":"toeverything/AFFiNE","slug":"doc-not-found-523e8f","errorCode":"doc_not_found","errorMessage":"Doc ${docId} under Space ${spaceId} not found.","messagePattern":"Doc (.+?) under Space (.+?) not found\\.","errorType":"exception","errorClass":"DocNotFound","httpStatus":404,"severity":"error","filePath":"packages/backend/server/src/core/workspaces/resolvers/doc.ts","lineNumber":335,"sourceCode":"    private readonly event: EventBus,\n    private readonly runtime: BackendRuntimeProvider\n  ) {}\n\n  @ResolveField(() => WorkspaceDocMeta, {\n    description: 'Cloud page metadata of workspace',\n    complexity: 2,\n    deprecationReason: 'use [WorkspaceType.doc] instead',\n  })\n  async pageMeta(\n    @CurrentUser() me: CurrentUser,\n    @Parent() workspace: WorkspaceType,\n    @Args('pageId') pageId: string\n  ) {\n    await this.ac.user(me.id).doc(workspace.id, pageId).assert('Doc.Read');\n\n    const metadata = await this.models.doc.getAuthors(workspace.id, pageId);\n    if (!metadata) {\n      throw new DocNotFound({ spaceId: workspace.id, docId: pageId });\n    }\n\n    return {\n      createdAt: metadata.createdAt,\n      updatedAt: metadata.updatedAt,\n      createdBy: metadata.createdByUser || null,\n      updatedBy: metadata.updatedByUser || null,\n    };\n  }\n\n  @ResolveField(() => [DocType], {\n    description: 'Get public docs of a workspace',\n    complexity: 2,\n  })\n  async publicDocs(@Parent() workspace: WorkspaceType) {\n    return this.models.doc.findPublics(workspace.id);\n  }\n","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/2af30773aecd567f09b346e7b72fc69143144057/packages/backend/server/src/core/workspaces/resolvers/doc.ts#L317-L353","documentation":"The deprecated Workspace.pageMeta resolver loads author metadata with models.doc.getAuthors; a null result means no cloud doc record exists for (workspaceId, pageId) — the page was never synced to the cloud, was deleted, or the id is not a doc in that space. Doc.Read can pass at workspace scope even though the doc row itself is absent, so the missing metadata is what surfaces.","triggerScenarios":"Querying pageMeta(pageId) with an id that has no doc record in that workspace; the doc being deleted between the permission check and the metadata load; a local-only page that was never synced to the cloud.","commonSituations":"Clients still on the deprecated pageMeta field; deep links or bookmarks holding stale page ids; races right after doc deletion.","solutions":["Query the doc itself (the WorkspaceType.doc field) first and handle a null doc before asking for metadata","Migrate off the deprecated pageMeta field — the deprecation reason points to WorkspaceType.doc","Ensure the page is synced to the cloud before requesting cloud metadata"],"exampleFix":"# before (GraphQL)\nquery meta($wsId: String!, $pageId: String!) {\n  workspace(id: $wsId) {\n    pageMeta(pageId: $pageId) { createdAt updatedAt } # throws DOC_NOT_FOUND for unknown ids\n  }\n}\n\n# after\nquery doc($wsId: String!, $pageId: String!) {\n  workspace(id: $wsId) {\n    doc(pageId: $pageId) { # returns null instead of throwing\n      meta { createdAt updatedAt }\n    }\n  }\n}","handlingStrategy":"validation","validationCode":"// Confirm the doc exists before asking the deprecated pageMeta field\nconst doc = await workspaceDoc(ws.id, pageId);\nif (!doc) {\n  handleMissingPage(pageId);\n} else {\n  const meta = await pageMeta(ws.id, pageId);\n}","typeGuard":"function isDocNotFound(e: unknown): boolean {\n  return (\n    typeof e === 'object' && e !== null &&\n    (e as { extensions?: { code?: string } }).extensions?.code === 'doc_not_found'\n  );\n}","tryCatchPattern":"try {\n  meta = await pageMeta(ws.id, pageId);\n} catch (e) {\n  if (isDocNotFound(e)) {\n    dropPageFromCache(pageId); // doc is gone; stop requesting its metadata\n  } else throw e;\n}","preventionTips":["Prefer the WorkspaceType.doc field over the deprecated pageMeta resolver","Validate page ids from URLs/deep links against the synced doc list before querying cloud metadata","Purge local references to deleted docs when the doc list refreshes"],"tags":["doc","not-found","graphql","deprecated","affine"],"backgroundTag":"resource-not-found","analyzedSha":"2af30773aecd567f09b346e7b72fc69143144057","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}