{"record":{"id":"1dc2ed01df6cbb12","repo":"toeverything/AFFiNE","slug":"user-not-found-1dc2ed","errorCode":"user_not_found","errorMessage":"User not found.","messagePattern":"User not found\\.","errorType":"http","errorClass":"UserNotFound","httpStatus":404,"severity":"error","filePath":"packages/backend/server/src/core/workspaces/resolvers/member.ts","lineNumber":620,"sourceCode":"    return true;\n  }\n\n  @Throttle('strict')\n  @Public()\n  @Query(() => InvitationType, {\n    description: 'get workspace invitation info',\n  })\n  async getInviteInfo(\n    @CurrentUser() user: UserType | undefined,\n    @Args('inviteId') inviteId: string\n  ): Promise<InvitationType> {\n    const { workspaceId, inviteeUserId, isLink } =\n      await this.workspaceService.getInviteInfo(inviteId);\n    const workspace = await this.workspaceService.getWorkspaceInfo(workspaceId);\n    const owner = await this.models.workspaceUser.getOwner(workspaceId);\n\n    const inviteeId = inviteeUserId || user?.id;\n    if (!inviteeId) throw new UserNotFound();\n    const invitee = await this.models.user.getWorkspaceUser(inviteeId);\n    if (!invitee) throw new UserNotFound();\n\n    let status: WorkspaceMemberStatus | undefined;\n    if (isLink) {\n      const invitation = await this.models.workspaceUser.get(\n        workspaceId,\n        inviteeId\n      );\n      status = invitation?.status;\n    } else {\n      const invitation = await this.models.workspaceUser.getById(inviteId);\n      status = invitation?.status;\n    }\n\n    return { workspace, user: owner, invitee, status };\n  }\n","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/core/workspaces/resolvers/member.ts#L602-L638","documentation":"Thrown by the getInviteInfo query when no invitee can be resolved: inviteeUserId from the invite is empty AND no current user is supplied, or the resolved inviteeId does not map to a workspace user record (models.user.getWorkspaceUser returns null). Reported as user_not_found (resource_not_found, HTTP 404).","triggerScenarios":"Calling getInviteInfo(inviteId) where the invite has no bound invitee and the request is anonymous, or the invitee id no longer corresponds to a user.","commonSituations":"Anonymous visitor opens an invite whose invitee record was deleted; the invite link is malformed/stale so inviteeUserId is empty and there is no session; the user account was hard-deleted after the invite was created.","solutions":["Ensure the caller is authenticated when the invite has no specific inviteeUserId (link invites).","Validate the inviteId still maps to a live invite via the workspace service before calling getInviteInfo.","Handle user_not_found in the UI by prompting sign-in or showing an 'invite no longer valid' state."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure a session exists before fetching link-invite info\nif (!currentUser && !inviteIdHasInvitee(inviteId)) {\n  redirectToSignIn();\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await getInviteInfo(inviteId);\n} catch (e) {\n  if (isGraphQLError(e, 'user_not_found')) showInviteInvalidNotice();\n  else throw e;\n}","preventionTips":["Require authentication before resolving link invites that have no bound invitee.","Validate the inviteId is live before deep-linking to invite info.","Show a clear 'invite no longer valid' state on user_not_found."],"tags":["graphql","invite","auth","workspace","state"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}