plandex-ai/plandex · error

error deleting org user: %v

Error message

error deleting org user: %v

What it means

The org-user deletion handler runs db.DeleteOrgUser inside db.WithTx. If the delete fails, the transaction is rolled back and the error is wrapped as 'error deleting org user', returning HTTP 500 to the caller.

Source

Thrown at app/server/handlers/users.go:194

			log.Printf("Error getting number of org owners: %v\n", err)
			http.Error(w, "Error getting number of org owners: "+err.Error(), http.StatusInternalServerError)
			return
		}

		if numOwners == 1 {
			log.Println("Cannot delete the only org owner")
			http.Error(w, "Cannot delete the only org owner", http.StatusForbidden)
			return
		}
	}

	err = db.WithTx(r.Context(), "delete org user", func(tx *sqlx.Tx) error {

		err = db.DeleteOrgUser(auth.OrgId, userId, tx)

		if err != nil {
			log.Println("Error deleting org user: ", err)
			return fmt.Errorf("error deleting org user: %v", err)
		}

		invite, err := db.GetActiveInviteByEmail(auth.OrgId, auth.User.Email)

		if err != nil {
			log.Println("Error getting invite for org user: ", err)
			return fmt.Errorf("error getting invite for org user: %v", err)
		}

		if invite != nil {
			err = db.DeleteInvite(invite.Id, tx)

			if err != nil {
				log.Println("Error deleting invite: ", err)
				return fmt.Errorf("error deleting invite: %v", err)
			}
		}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the wrapped cause; FK violations are the usual culprit.
  2. Delete or reassign dependent rows (plans, streams) before removing the org user.
  3. Add ON DELETE CASCADE or an explicit cleanup in the same transaction.
  4. Guard against double-delete by checking membership before deleting.

Example fix

// before
err = db.DeleteOrgUser(auth.OrgId, userId, tx)
// after
if _, err := db.GetOrgUser(auth.OrgId, userId); err != nil {
    return fmt.Errorf("org user not found")
}
err = db.DeleteOrgUser(auth.OrgId, userId, tx)
Defensive patterns

Strategy: validation

Validate before calling

// Go - verify membership and no dependents before deleting
if _, err := db.GetOrgUser(auth.OrgId, userId); err != nil {
    return fmt.Errorf("user is not a member of this org")
}

Try / catch

err = db.WithTx(ctx, "delete org user", func(tx *sqlx.Tx) error {
    if err := db.DeleteOrgUser(auth.OrgId, userId, tx); err != nil {
        if isForeignKeyErr(err) {
            return errUserHasDependents
        }
        return fmt.Errorf("error deleting org user: %v", err)
    }
    return nil
})

Prevention

When it happens

Trigger: db.DeleteOrgUser fails: FK constraints from rows still referencing the org_user (plans, streams, assignments), non-existent org/user pair, permission/ownership violation, deadlock, or DB connection loss.

Common situations: Removing a user who still owns or is assigned to plans/branches; deleting an already-removed member (double DELETE); cascade rules missing in the schema.

Related errors


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