makeplane/plane · error · Error
Member not found
Error message
Member not found
What it means
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.
Source
Thrown at apps/web/core/store/member/project/base-project-member.store.ts:351
/**
* @description Returns the role to use when updating a project member
* @param projectId
* @param userId
* @param role
*/
getProjectMemberRoleForUpdate = (_projectId: string, _userId: string, role: EUserProjectRoles): EUserProjectRoles =>
role;
/**
* @description update the role of a member in a project
* @param workspaceSlug
* @param projectId
* @param userId
* @param data
*/
updateMemberRole = async (workspaceSlug: string, projectId: string, userId: string, role: EUserProjectRoles) => {
const memberDetails = this.getProjectMemberDetails(userId, projectId);
if (!memberDetails || !memberDetails?.id) throw new Error("Member not found");
// original data to revert back in case of error
const isCurrentUser = this.rootStore.user.data?.id === userId;
const membershipBeforeUpdate = { ...this.getProjectMembershipByUserId(userId, projectId) };
const permissionBeforeUpdate = isCurrentUser
? this.rootStore.user.permission.getProjectRoleByWorkspaceSlugAndProjectId(workspaceSlug, projectId)
: undefined;
const updatedProjectRole = this.getProjectMemberRoleForUpdate(projectId, userId, role);
try {
runInAction(() => {
set(this.projectMemberMap, [projectId, userId, "original_role"], role);
set(this.projectMemberMap, [projectId, userId, "role"], updatedProjectRole);
if (isCurrentUser) {
set(
this.rootStore.user.permission.workspaceProjectsPermissions,
[workspaceSlug, projectId],
updatedProjectRole
);
}View on GitHub (pinned to 1c8a60f858)
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.
Example fix
// before: action invoked even when member not in store
updateMemberRole = async (workspaceSlug, projectId, userId, role) => {
const memberDetails = this.getProjectMemberDetails(userId, projectId);
if (!memberDetails || !memberDetails?.id) throw new Error("Member not found");
// after: caller-side guard prevents the call
const canChange = Boolean(this.getProjectMemberDetails(userId, projectId)?.id);
if (!canChange) return; Defensive patterns
Strategy: validation
Validate before calling
const member = projectMemberStore.getProjectMemberDetails(userId, projectId);
if (!member?.id) {
await projectMemberStore.fetchProjectMembers(workspaceSlug, projectId);
return;
} Type guard
const hasMemberId = (m: unknown): m is { id: string } =>
typeof m === 'object' && m !== null && typeof (m as any).id === 'string'; Try / catch
try { await updateMemberRole(workspaceSlug, projectId, userId, role); }
catch (e) { showRoleUpdateError(); } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Member not found
- Workspace not found
- Missing required fields.
- Publish settings not found
- Issue not found
AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12).
Data as JSON: /api/errors/a77a53e41de96e6f.
Report an issue: GitHub.