{"record":{"id":"d1a4aba2326a2cf5","repo":"toeverything/AFFiNE","slug":"not-found-d1a4ab","errorCode":"not_found","errorMessage":"Invitation not found","messagePattern":"Invitation not found","errorType":"exception","errorClass":"NotFound","httpStatus":404,"severity":"error","filePath":"packages/backend/server/src/core/workspaces/service.ts","lineNumber":124,"sourceCode":"    return storageUserIds;\n  }\n\n  async getInviteInfo(inviteId: string): Promise<InviteInfo> {\n    // invite link\n    const invite = await this.cache.get<InviteInfo>(\n      `workspace:inviteLinkId:${inviteId}`\n    );\n    if (typeof invite?.workspaceId === 'string') {\n      return {\n        ...invite,\n        isLink: true,\n      };\n    }\n\n    const workspaceUser = await this.models.workspaceUser.getById(inviteId);\n\n    if (!workspaceUser) {\n      throw new NotFound('Invitation not found');\n    }\n\n    return {\n      isLink: false,\n      workspaceId: workspaceUser.workspaceId,\n      inviteeUserId: workspaceUser.userId,\n      inviterUserId: workspaceUser.inviterId,\n    };\n  }\n\n  async getWorkspaceInfo(workspaceId: string) {\n    const workspaceContent = await this.doc.getWorkspaceContent(workspaceId);\n\n    let avatar = DEFAULT_WORKSPACE_AVATAR;\n    if (workspaceContent?.avatarKey) {\n      try {\n        const owner = await this.models.workspaceUser.getOwner(workspaceId);\n        avatar = (","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/2af30773aecd567f09b346e7b72fc69143144057/packages/backend/server/src/core/workspaces/service.ts#L106-L142","documentation":"Thrown by WorkspaceService invite-info lookup when inviteId is neither a cached link invitation ('workspace:inviteLinkId:<id>') nor an existing workspaceUser record — i.e. the invitation identifier does not exist anymore (or never did).","triggerScenarios":"Calling the invite info query with an expired/already-consumed link invite id, an invitation record that was deleted (member removed), or a fabricated id.","commonSituations":"User opens an old invite page whose link invite expired in cache; the invited member was removed so the workspaceUser row is gone; self-hosted Redis flush wiped pending link invites.","solutions":["Ask the workspace owner to send a fresh invitation (link or email).","Verify the inviteId matches the one embedded in the invite URL exactly.","Self-hosted: confirm the cache (Redis) is running and was not flushed, since link invites live only in cache."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const info = await gql.request(GET_INVITE_INFO, { inviteId });\n} catch (e) {\n  if (getGraphqlErrorCode(e) === 'not_found') {\n    renderExpiredInvitePage(inviteId);\n  }\n}","preventionTips":["Always resolve invite info before rendering an invite page; treat not_found as 'expired invitation'.","Ask owners to generate fresh links rather than reusing old ones across long periods."],"tags":["workspace","invitation","not-found","cache"],"backgroundTag":"invitation-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"}