{"record":{"id":"a77a53e41de96e6f","repo":"makeplane/plane","slug":"member-not-found","errorCode":null,"errorMessage":"Member not found","messagePattern":"Member not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/web/core/store/member/project/base-project-member.store.ts","lineNumber":351,"sourceCode":"  /**\n   * @description Returns the role to use when updating a project member\n   * @param projectId\n   * @param userId\n   * @param role\n   */\n  getProjectMemberRoleForUpdate = (_projectId: string, _userId: string, role: EUserProjectRoles): EUserProjectRoles =>\n    role;\n\n  /**\n   * @description update the role of a member in a project\n   * @param workspaceSlug\n   * @param projectId\n   * @param userId\n   * @param data\n   */\n  updateMemberRole = async (workspaceSlug: string, projectId: string, userId: string, role: EUserProjectRoles) => {\n    const memberDetails = this.getProjectMemberDetails(userId, projectId);\n    if (!memberDetails || !memberDetails?.id) throw new Error(\"Member not found\");\n    // original data to revert back in case of error\n    const isCurrentUser = this.rootStore.user.data?.id === userId;\n    const membershipBeforeUpdate = { ...this.getProjectMembershipByUserId(userId, projectId) };\n    const permissionBeforeUpdate = isCurrentUser\n      ? this.rootStore.user.permission.getProjectRoleByWorkspaceSlugAndProjectId(workspaceSlug, projectId)\n      : undefined;\n    const updatedProjectRole = this.getProjectMemberRoleForUpdate(projectId, userId, role);\n    try {\n      runInAction(() => {\n        set(this.projectMemberMap, [projectId, userId, \"original_role\"], role);\n        set(this.projectMemberMap, [projectId, userId, \"role\"], updatedProjectRole);\n        if (isCurrentUser) {\n          set(\n            this.rootStore.user.permission.workspaceProjectsPermissions,\n            [workspaceSlug, projectId],\n            updatedProjectRole\n          );\n        }","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/web/core/store/member/project/base-project-member.store.ts#L333-L369","documentation":"Thrown by updateMemberRole in the project member store when getProjectMemberDetails(userId, projectId) returns falsy or has no id. This is a precondition check before the optimistic role update + REST call to updateProjectMember, ensuring the local store has a member record to revert to on failure.","triggerScenarios":"Opening a project member's role dropdown and saving before the project member list for that project has been fetched/loaded into projectMemberMap; the userId passed in does not correspond to any member of that project (already removed, or never a member); the member record exists but its id field is unset due to a partial store hydration.","commonSituations":"Admin opens the members panel via a deep link before the member list request resolves; race after a member was just removed in another tab; stale userId from a closed panel; SSR/initial render firing the action before data is in.","solutions":["Ensure fetchProjectMembers for the project has resolved before enabling the role-change action (gate the UI on member presence).","Re-fetch the project member list and retry; the member may simply not be loaded yet.","Confirm the userId is still a project member — if removed elsewhere, refresh state and remove the row.","Guard the action with a getProjectMemberDetails check at the call site and show a loading state instead of invoking."],"exampleFix":"// before: action invoked even when member not in store\nupdateMemberRole = async (workspaceSlug, projectId, userId, role) => {\n  const memberDetails = this.getProjectMemberDetails(userId, projectId);\n  if (!memberDetails || !memberDetails?.id) throw new Error(\"Member not found\");\n// after: caller-side guard prevents the call\nconst canChange = Boolean(this.getProjectMemberDetails(userId, projectId)?.id);\nif (!canChange) return;","handlingStrategy":"validation","validationCode":"const member = projectMemberStore.getProjectMemberDetails(userId, projectId);\nif (!member?.id) {\n  await projectMemberStore.fetchProjectMembers(workspaceSlug, projectId);\n  return;\n}","typeGuard":"const hasMemberId = (m: unknown): m is { id: string } =>\n  typeof m === 'object' && m !== null && typeof (m as any).id === 'string';","tryCatchPattern":"try { await updateMemberRole(workspaceSlug, projectId, userId, role); }\ncatch (e) { showRoleUpdateError(); }","preventionTips":["Disable the role dropdown until the member is loaded in the store.","Refetch members if the row is missing rather than invoking the action.","Handle the throw at the UI boundary with a user-facing message."],"tags":["members","web","project","roles","store-lookup","precondition"],"backgroundTag":null,"analyzedSha":"1c8a60f858d8472aa56e29994ec1c7926da2c6ce","analyzedAt":"2026-08-12T14:44:31.636Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}