{"record":{"id":"24879a9b525b2e62","repo":"toeverything/AFFiNE","slug":"invalid-invitation","errorCode":"invalid_invitation","errorMessage":"Invalid invitation provided.","messagePattern":"Invalid invitation provided\\.","errorType":"exception","errorClass":"InvalidInvitation","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/core/workspaces/resolvers/member.ts","lineNumber":580,"sourceCode":"\n    return true;\n  }\n\n  @Mutation(() => Boolean)\n  async acceptInviteById(\n    @CurrentUser() user: CurrentUser,\n    @Args('inviteId') inviteId: string,\n    @Args('workspaceId', { deprecationReason: 'never used', nullable: true })\n    _workspaceId: string,\n    @Args('sendAcceptMail', {\n      nullable: true,\n      deprecationReason: 'never used',\n    })\n    _sendAcceptMail: boolean\n  ) {\n    const role = await this.models.workspaceUser.getById(inviteId);\n    // invitation by email\n    if (role) {\n      if (user.id !== role.userId) {\n        throw new InvitationAccountMismatch();\n      }\n\n      await this.acceptInvitationByEmail(role);\n    } else {\n      // invitation by link\n      const invitation = await this.cache.get<{\n        workspaceId: string;\n        inviterUserId: string;\n      }>(`workspace:inviteLinkId:${inviteId}`);\n\n      if (!invitation) {\n        throw new InvalidInvitation();\n      }\n\n      const role = await this.models.workspaceUser.get(\n        invitation.workspaceId,","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/2af30773aecd567f09b346e7b72fc69143144057/packages/backend/server/src/core/workspaces/resolvers/member.ts#L562-L598","documentation":"Thrown by the acceptInvitation GraphQL mutation when the inviteId resolves to an existing email invitation (a workspaceUser record), but the currently signed-in user's id does not match the invited user (role.userId). AFFiNE binds email invitations to one user, so a different account cannot consume them.","triggerScenarios":"Calling acceptInvitation(inviteId) while authenticated as a user other than the one whose email received the invitation, e.g. the invitee clicks the accept link in the mail but the browser session belongs to another account (or a service/test account).","commonSituations":"Multiple accounts in one browser (personal + work), clicking an old invitation after switching accounts, or forwarding an invitation email to a teammate who tries to accept it from their own session.","solutions":["Sign out and sign back in as the exact user the invitation email was addressed to, then retry acceptInvitation.","If the invitee should be different, ask the workspace owner to send a new invitation to the correct email address.","Verify you are passing the inviteId of an email invitation and not a link invitation id (link invites take a different code path)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before accepting, fetch invite info and compare the invitee with the session user\nconst invite = await gql.request(GET_INVITE_INFO, { inviteId });\nif (!invite.isLink && invite.inviteeUserId && invite.inviteeUserId !== currentUser.id) {\n  // wrong account signed in — prompt switch instead of calling acceptInvitation\n  showSignInAs(invite.inviteeUserId);\n} else {\n  await gql.request(ACCEPT_INVITATION, { inviteId });\n}","typeGuard":null,"tryCatchPattern":"try {\n  await acceptInvitation(inviteId);\n} catch (e) {\n  if (getErrorCode(e) === 'invalid_invitation' && isEmailInvite) {\n    // signed in as the wrong account — surface account-switch UI\n  }\n}","preventionTips":["Fetch invite info first and compare inviteeUserId with the current session user before calling acceptInvitation.","In the frontend invite flow, show which account is signed in before the accept step."],"tags":["workspace","invitation","graphql","authorization","member"],"backgroundTag":"invitation-invalid","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"}