Files
twenty/packages
Sonarly Claude Code 2181fb541e fix: handle deleted UserWorkspace in contact creation and connected account cleanup
https://sonarly.com/issue/26526?type=bug

When a user is removed from a workspace (via workspace-member deletion or user removal), the
    UserWorkspace row is hard-deleted synchronously, but the associated ConnectedAccount rows are
    only cleaned up asynchronously via a BullMQ job (DeleteWorkspaceMemberConnectedAccountsCleanupJob).
    That cleanup job has a bug: it queries for the workspace member without `withDeleted: true`,
    finds nothing (the member is already soft-deleted), and silently returns — never deleting the
    connected accounts. The orphaned connected accounts continue syncing email, and when new
    contacts are discovered, the CreateCompanyAndContactJob tries to look up the now-deleted
    UserWorkspace by its stale `userWorkspaceId`, throwing:
      `Error: UserWorkspace with id efe7fd46-238b-464f-b3a4-19c72c4f0141 not found`

    This failure path was introduced by commit d3f0162cf5 (2026-04-06, "Remove connected account
    feature flag"), which changed ConnectedAccount from a workspace entity (with a direct
    `accountOwnerId` → WorkspaceMember relation) to a core entity (with a `userWorkspaceId` UUID
    column and no foreign key to UserWorkspace). The old code looked up the account owner directly;
    the new code adds an intermediate UserWorkspace lookup that breaks when the row is gone.

Fix: Two changes that work together to fix the crash:

1. **create-company-and-contact.service.ts** (proximate fix): When UserWorkspace is not found, return `null` instead of throwing. The downstream `createCompaniesAndPeople()` already accepts `accountOwner: WorkspaceMemberWorkspaceEntity | null` and handles it gracefully — contacts are still created, just without a `createdBy.workspaceMemberId`. This stops the Sentry error immediately.

2. **delete-workspace-member-connected-accounts.job.ts** (root cause fix): Three changes:
   - Added `withDeleted: true` to the workspace member query so soft-deleted members are still found
   - Added `shouldBypassPermissionChecks: true` to the repository (consistent with other system jobs)
   - Added fallback path: when UserWorkspace is already hard-deleted, scan for orphaned connected accounts in the workspace (accounts whose `userWorkspaceId` references a non-existent UserWorkspace row) and delete them

Together: the cleanup job now actually cleans up connected accounts when a member is removed, AND the contact creation service no longer crashes if an orphaned account still manages to trigger a sync.
2026-04-15 09:07:51 +00:00
..
2026-04-13 15:13:11 +02:00
2026-04-14 18:38:55 +02:00