plandex-ai/plandex · warning
User does not have permission to remove user with role: {org
Error message
User does not have permission to remove user with role: {orgUser.OrgRoleId} What it means
The authenticated caller lacks the composite permission "remove-user|<targetOrgRoleId>", so DeleteOrgUserHandler refuses with HTTP 403. The permission is dynamically built by joining PermissionRemoveUser with the target user's OrgRoleId, meaning callers need a matching grant per target role (e.g. separate grants for removing members vs admins vs owners).
Source
Thrown at app/server/handlers/users.go:144
vars := mux.Vars(r)
userId := vars["userId"]
log.Println("userId: ", userId)
orgUser, err := db.GetOrgUser(userId, auth.OrgId)
if err != nil {
log.Printf("Error getting org user: %v\n", err)
http.Error(w, "Error getting org user: "+err.Error(), http.StatusInternalServerError)
return
}
// ensure current user can remove target user
removePermission := shared.Permission(strings.Join([]string{string(shared.PermissionRemoveUser), orgUser.OrgRoleId}, "|"))
if !auth.HasPermission(removePermission) {
log.Printf("User does not have permission to remove user with role: %v\n", orgUser.OrgRoleId)
http.Error(w, "User does not have permission to remove user with role: "+orgUser.OrgRoleId, http.StatusForbidden)
return
}
// verify user is org member
isMember, err := db.ValidateOrgMembership(userId, auth.OrgId)
if err != nil {
log.Printf("Error validating org membership: %v\n", err)
http.Error(w, "Error validating org membership: "+err.Error(), http.StatusInternalServerError)
return
}
if !isMember {
log.Printf("User %s is not a member of org %s\n", userId, auth.OrgId)
http.Error(w, "User "+userId+" is not a member of org "+auth.OrgId, http.StatusForbidden)
return
}
View on GitHub (pinned to e2d772072e)
Solutions
- Grant the caller's role the permission string remove-user|<orgUser.OrgRoleId> (exact pipe-joined form) in role config
- Check which role the target user has (org_users.org_role_id) and confirm your permission covers that specific role
- Re-authenticate to refresh permissions if role grants were changed recently
- Use a role with sufficient privileges (e.g. org owner) to perform the removal
Defensive patterns
Strategy: validation
Validate before calling
required := "remove-user|" + targetOrgRoleId
hasIt := slices.Contains(callerPermissions, required)
if !hasIt {
return fmt.Errorf("missing permission %s", required)
} Type guard
func canRemoveUser(perms []shared.Permission, targetRoleId string) bool {
p := shared.Permission("remove-user|" + targetRoleId)
return slices.Contains(perms, p)
} Try / catch
if !auth.HasPermission(removePermission) {
http.Error(w, "forbidden: missing "+string(removePermission), http.StatusForbidden)
return
}
// client side:
// if resp.StatusCode == http.StatusForbidden { stop; surface 'insufficient permissions' } Prevention
- Grant per-role removal permissions in the exact pipe-joined format remove-user|<role>
- Re-issue tokens after changing role grants so permissions are fresh
- Document which roles may remove which target roles for API consumers
- Pre-check permissions client-side and disable delete actions that would 403
When it happens
Trigger: Caller's role permission set does not include remove-user|<role> for the specific OrgRoleId of the target user — e.g. an admin tries to delete another admin or an owner, or a member tries to delete anyone.
Common situations: Role config updated but the caller's cached JWT still has old permissions; only owner-level removal was granted but target is an admin; reusing an integration token with a read-only role; per-role permission scheme misunderstood by API consumers.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- User does not have permission to rename project
- User does not have permission to delete project
- User does not have permission to update plan
- User does not have permission to delete plan
- User does not have permission to rename plan
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/e6bb70c26da3de91.
Report an issue: GitHub.