{"record":{"id":"17e78a9c13a405db","repo":"toeverything/AFFiNE","slug":"cannot-delete-account-with-owned-team-workspace","errorCode":"cannot_delete_account_with_owned_team_workspace","errorMessage":"Cannot delete account. You are the owner of one or more team workspaces. Please transfer ownership or delete them first.","messagePattern":"Cannot delete account\\. You are the owner of one or more team workspaces\\. Please transfer ownership or delete them first\\.","errorType":"error_code","errorClass":"CannotDeleteAccountWithOwnedTeamWorkspace","httpStatus":403,"severity":"error","filePath":"packages/backend/server/src/models/user.ts","lineNumber":294,"sourceCode":"    return user;\n  }\n\n  async ownedWorkspaces(id: string) {\n    return await this.models.workspaceUser.getUserActiveRoles(id, {\n      role: WorkspaceRole.Owner,\n    });\n  }\n\n  async delete(id: string) {\n    const ownedWorkspaces = await this.ownedWorkspaces(id);\n\n    for (const ws of ownedWorkspaces) {\n      const isTeamWorkspace = await this.models.workspace.isTeamWorkspace(\n        ws.workspaceId\n      );\n\n      if (isTeamWorkspace) {\n        throw new CannotDeleteAccountWithOwnedTeamWorkspace();\n      }\n    }\n\n    await this.event.emitAsync('user.preDelete', { id });\n\n    await this.db.workspaceInvitation.deleteMany({\n      where: { inviteeUserId: id },\n    });\n\n    const user = await this.db.user.delete({ where: { id } });\n\n    this.event.emit('user.deleted', {\n      ...user,\n      ownedWorkspaces: ownedWorkspaces.map(r => r.workspaceId),\n    });\n\n    return user;\n  }","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/models/user.ts#L276-L312","documentation":"Thrown by UserModel.delete (user.ts:294) when the user owns any workspace that is a team workspace (isTeamWorkspace === true). Team workspaces must not be orphaned, so ownership must be transferred or the workspace deleted before the account can be removed. UserFriendlyError, code cannot_delete_account_with_owned_team_workspace, type action_forbidden, HTTP 403.","triggerScenarios":"DELETE /user (account deletion) for a user who owns one or more team workspaces.","commonSituations":"Admin removes a former employee who still owns team workspaces; self-service 'delete my account' is blocked because the user forgot to hand over a team workspace; ownership of a team workspace was never transferred off the user.","solutions":["Transfer ownership of each team workspace via setOwner to another active member.","Or delete those team workspaces if they are no longer needed.","Retry account deletion once no team workspace lists the user as owner. (Personal / non-team workspaces do not block deletion.)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async function canDeleteAccount(models, userId: string): Promise<boolean> {\n  const owned = await models.user.ownedWorkspaces(userId);\n  for (const ws of owned) {\n    if (await models.workspace.isTeamWorkspace(ws.workspaceId)) return false;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"import { CannotDeleteAccountWithOwnedTeamWorkspace } from '../base/error/errors.gen';\n\ntry {\n  await models.user.delete(id);\n} catch (e) {\n  if (e instanceof CannotDeleteAccountWithOwnedTeamWorkspace) {\n    // list the blocking team workspaces and prompt to transfer ownership\n  } else throw e;\n}","preventionTips":["Pre-check ownedWorkspaces + isTeamWorkspace before showing 'delete account'.","Transfer team-workspace ownership as part of offboarding.","Block the delete action in the UI while any team workspace is owned."],"tags":["account","workspace","ownership","team"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}