[PR #32151] fix(api): clean up orphaned pending accounts on member removal #33580

Closed
opened 2026-02-21 20:53:32 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langgenius/dify/pull/32151

State: closed
Merged: Yes


Important

  1. Make sure you have read our contribution guidelines
  2. Ensure there is an associated issue and you have been assigned to it
  3. Use the correct syntax to link this PR: Fixes #<issue number>.

Summary

Fixes #31092

When an admin removes a member from a workspace, only the TenantAccountJoin record is deleted. For pending accounts (invited but never activated), this leaves an orphaned Account row that can never log in and serves no purpose.

This PR adds cleanup logic to TenantService.remove_member_from_tenant():

  • After deleting the join record, checks if the removed account has status == PENDING
  • If pending, counts remaining TenantAccountJoin records for that account
  • If zero remaining memberships, deletes the orphaned account

Safeguards:

  • Only affects PENDING accounts — active/banned/closed accounts are never touched
  • Only deletes when zero workspace memberships remain (safe for multi-workspace invites)
  • Account identifiers are captured before deletion to avoid SQLAlchemy DetachedInstanceError from expire_on_commit

Screenshots

N/A — backend-only change, no UI impact.

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran make lint and make type-check (backend) and cd web && npx lint-staged (frontend) to appease the lint gods
**Original Pull Request:** https://github.com/langgenius/dify/pull/32151 **State:** closed **Merged:** Yes --- > [!IMPORTANT] > > 1. Make sure you have read our [contribution guidelines](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) > 1. Ensure there is an associated issue and you have been assigned to it > 1. Use the correct syntax to link this PR: `Fixes #<issue number>`. ## Summary Fixes #31092 When an admin removes a member from a workspace, only the `TenantAccountJoin` record is deleted. For **pending** accounts (invited but never activated), this leaves an orphaned `Account` row that can never log in and serves no purpose. This PR adds cleanup logic to `TenantService.remove_member_from_tenant()`: - After deleting the join record, checks if the removed account has `status == PENDING` - If pending, counts remaining `TenantAccountJoin` records for that account - If zero remaining memberships, deletes the orphaned account **Safeguards:** - Only affects `PENDING` accounts — active/banned/closed accounts are never touched - Only deletes when zero workspace memberships remain (safe for multi-workspace invites) - Account identifiers are captured before deletion to avoid SQLAlchemy `DetachedInstanceError` from `expire_on_commit` ## Screenshots N/A — backend-only change, no UI impact. ## Checklist - [ ] This change requires a documentation update, included: [Dify Document](https://github.com/langgenius/dify-docs) - [x] I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!) - [x] I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change. - [x] I've updated the documentation accordingly. - [x] I ran `make lint` and `make type-check` (backend) and `cd web && npx lint-staged` (frontend) to appease the lint gods
yindo added the pull-request label 2026-02-21 20:53:32 -05:00
yindo closed this issue 2026-02-21 20:53:32 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#33580