plandex-ai/plandex · warning

User does not have permission to invite user with role:

Error message

User does not have permission to invite user with role: 

What it means

Before creating an invite, the handler composes the permission 'invite_user|<orgRoleId>' and checks it with auth.HasPermission. If the authenticated user lacks that role-scoped invite permission, the handler responds 403 with this message naming the requested OrgRoleId.

Source

Thrown at app/server/handlers/invites.go:70

	}

	currentUserId := auth.User.Id

	var req shared.InviteRequest
	err = json.NewDecoder(r.Body).Decode(&req)
	if err != nil {
		log.Printf("Error unmarshalling request: %v\n", err)
		http.Error(w, "Error unmarshalling request: "+err.Error(), http.StatusInternalServerError)
		return
	}
	req.Email = strings.ToLower(req.Email)

	// ensure current user can invite target user
	permission := shared.Permission(strings.Join([]string{string(shared.PermissionInviteUser), req.OrgRoleId}, "|"))

	if !auth.HasPermission(permission) {
		log.Printf("User does not have permission to invite user with role: %v\n", req.OrgRoleId)
		http.Error(w, "User does not have permission to invite user with role: "+req.OrgRoleId, http.StatusForbidden)
		return
	}

	// ensure user doesn't already have access to org via domain
	split := strings.Split(req.Email, "@")
	if len(split) != 2 {
		log.Printf("Invalid email: %v\n", req.Email)
		http.Error(w, "Invalid email: "+req.Email, http.StatusBadRequest)
		return
	}
	domain := &split[1]

	if org.AutoAddDomainUsers && org.Domain == domain {
		log.Printf("User already has access to org via domain: %v\n", domain)
		http.Error(w, "User already has access to org via domain: "+*domain, http.StatusBadRequest)
	}

	// ensure user with this email isn't already in the org

View on GitHub (pinned to e2d772072e)

Solutions

  1. Verify the caller's role grants the 'invite_user|<orgRoleId>' permission; use an account with admin/owner rights or a role you are permitted to invite into
  2. Confirm req.OrgRoleId is the correct current role ID (fetch org roles from the API rather than hardcoding)
  3. Ask an org admin to grant your role the invite permission for the target role, or have an admin perform the invite
  4. Check you are authenticated with the intended account/token and not a personal vs org token mismatch

Example fix

// before
{ "email": "dev@example.com", "orgRoleId": "admin" }   // caller is a plain member
// after
{ "email": "dev@example.com", "orgRoleId": "developer" } // role the caller may invite into, or run as an admin
Defensive patterns

Strategy: type-guard

Validate before calling

// Before inviting, confirm the caller can invite into the target role
// e.g. fetch my role's permissions and check for 'invite_user|<orgRoleId>'
perms, err := client.GetMyPermissions(ctx)
if err != nil {
    return err
}
wanted := "invite_user|" + orgRoleID
if !slices.Contains(perms, wanted) {
    return fmt.Errorf("caller lacks permission %s — ask an admin or pick a permitted role", wanted)
}

Type guard

func canInvite(perms []string, orgRoleID string) bool {
    wanted := "invite_user|" + orgRoleID
    return slices.Contains(perms, wanted)
}

Try / catch

err := client.InviteUser(ctx, email, orgRoleID)
if err != nil && strings.Contains(err.Error(), "does not have permission to invite") {
    return fmt.Errorf("forbidden: cannot invite into role %s — escalate to an org admin", orgRoleID)
}

Prevention

When it happens

Trigger: Inviting a user while specifying an OrgRoleId the caller is not allowed to assign invites for — e.g. a member/developer-only user trying to invite someone as an admin, or passing an unknown/garbage OrgRoleId that no permission grants cover.

Common situations: Non-admin users attempting to invite admins; the client sending a hardcoded or stale orgRoleId (renamed or deleted role); trial or restricted org plans; API calls with a token belonging to a lower-privileged account than assumed.

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


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/d2bf10a53c8b6e65. Report an issue: GitHub.