plandex-ai/plandex · error
error deleting org member: %v
Error message
error deleting org member: %v
What it means
DeleteOrgUser wraps a failure of the DELETE FROM orgs_users into 'error deleting org member: %v'. Unlike a missing row (DELETE simply affects 0 rows and returns nil), this always means the statement itself errored.
Source
Thrown at app/server/db/org_helpers.go:187
// Join all value strings and execute a single query
stmt := fmt.Sprintf("INSERT INTO orgs_users (org_id, user_id, org_role_id) VALUES %s ON CONFLICT ON CONSTRAINT org_user_unique DO NOTHING", strings.Join(valueStrings, ","))
_, err = tx.Exec(stmt, valueArgs...)
if err != nil {
return fmt.Errorf("error adding org users: %v", err)
}
}
return nil
}
func DeleteOrgUser(orgId, userId string, tx *sqlx.Tx) error {
log.Printf("Deleting org user, org: %s | user: %s\n", orgId, userId)
_, err := tx.Exec("DELETE FROM orgs_users WHERE org_id = $1 AND user_id = $2", orgId, userId)
if err != nil {
return fmt.Errorf("error deleting org member: %v", err)
}
return nil
}
func CreateOrgUser(orgId, userId, orgRoleId string, tx *sqlx.Tx) error {
query := "INSERT INTO orgs_users (org_id, user_id, org_role_id) VALUES ($1, $2, $3)"
var err error
if tx == nil {
_, err = Conn.Exec(query, orgId, userId, orgRoleId)
} else {
_, err = tx.Exec(query, orgId, userId, orgRoleId)
}
if err != nil {
return fmt.Errorf("error adding org member: %v", err)
}
View on GitHub (pinned to e2d772072e)
Solutions
- Read the wrapped %v for pq error code 23503 and add ON DELETE CASCADE or explicit cleanup of dependent rows in the same transaction before the delete
- Verify the DB user has DELETE privilege on orgs_users
- If the tx was aborted earlier, fix the first failing statement — this error is secondary
- Retry the removal after resolving the constraint
Example fix
// before
_, err := tx.Exec("DELETE FROM orgs_users WHERE org_id = $1 AND user_id = $2", orgId, userId)
// after
// in migration: dependent tables reference orgs_users(id) ON DELETE CASCADE
_, err := tx.Exec("DELETE FROM orgs_users WHERE org_id = $1 AND user_id = $2", orgId, userId) Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check membership before delete
ok, err := db.ValidateOrgMembership(orgId, userId)
if err != nil || !ok { return fmt.Errorf("not a member") } Try / catch
err := db.DeleteOrgUser(orgId, userId, tx)
if err != nil {
var pqErr *pq.Error
if errors.As(err, &pqErr) && pqErr.Code == "23503" {
return fmt.Errorf("member has dependent records: %s", pqErr.Detail)
}
return err
} Prevention
- Add ON DELETE CASCADE (or explicit cleanup) for tables referencing orgs_users
- Clean dependent rows in the same tx before the delete
- Grant the app role DELETE privilege on orgs_users
- Distinguish 0-rows-deleted (not a member) from statement errors by checking RowsAffected if needed
When it happens
Trigger: tx.Exec('DELETE ...') fails: FK violation on rows referencing orgs_users (e.g. 23503 from dependent tables without ON DELETE), permission denied, connection drop, or aborted transaction from an earlier statement in DeleteOrgUserHandler's tx.
Common situations: Trying to remove a user who has dependent records (invites, api keys, session rows) tied by FK; DB role lacking DELETE privilege; connection reset mid-transaction.
Related errors
- error adding org membership: %v
- error adding org users: %v
- error adding convo tokens: %v
- error checking settings: %v
- error creating postgres driver: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/46fd85a20fc3ccbc.
Report an issue: GitHub.