Budibase/budibase · error · HTTPError
Please visit "Account" to delete this user
Error message
Please visit "Account" to delete this user
What it means
destroy() throws HTTPError(400) 'Please visit "Account" to delete this user' when the caller tries to delete their OWN user account while it is the verified root account holder in Budibase Cloud (not self-hosted, account portal enabled). Account holders must delete via the external Account portal so billing/tenancy is handled correctly.
Source
Thrown at packages/backend-core/src/users/db.ts:575
})
}
})
return response
}
static async destroy(id: string) {
const db = getGlobalDB()
const dbUser = (await db.get(id)) as User
const userId = dbUser._id as string
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
// root account holder can't be deleted from inside budibase
const email = dbUser.email
const account = await accountSdk.getAccount(email)
if (account) {
if (dbUser.userId === getIdentity()!._id) {
throw new HTTPError('Please visit "Account" to delete this user', 400)
} else {
throw new HTTPError("Account holder cannot be deleted", 400)
}
}
}
await platform.users.removeUser(dbUser)
await db.remove(userId, dbUser._rev!)
const creatorsToDelete = (await isCreatorAsync(dbUser)) ? 1 : 0
await UserDB.quotas.removeUsers(1, creatorsToDelete)
await eventHelpers.handleDeleteEvents(dbUser)
await cache.user.invalidateUser(userId)
await sessions.invalidateSessions(userId, { reason: "deletion" })
}
static async createAdminUser(View on GitHub (pinned to a81a902e9a)
Solutions
- Delete the account via the Budibase Account portal (account.budibase.app) instead of the in-product API
- Delete a different (non-account-holder) user, or have an admin remove the user while logged in as someone else
- In self-hosted environments set SELF_HOSTED=true / DISABLE_ACCOUNT_PORTAL=true so this guard is bypassed legitimately
Example fix
// before
await users.destroy(accountHolderUserId) // called as the account holder
// after
// direct the user to the account portal; only destroy non-holder users in-product
if (user.email !== accountHolderEmail) {
await users.destroy(user._id!)
} Defensive patterns
Strategy: try-catch
Validate before calling
// check before attempting self-deletion
const isAccountHolder = user.email === (await accountSdk.getAccount(user.email))?.email
if (isAccountHolder && !env.SELF_HOSTED) {
// direct the user to the Account portal instead of calling destroy
} Try / catch
try {
await users.destroy(userId)
} catch (e: any) {
if (e?.status === 400 && e?.message.includes("Account\" to delete")) {
redirectToDeleteViaAccountPortal()
} else throw e
} Prevention
- Hide/disable self-delete UI for account holders in cloud deployments
- Check env.SELF_HOSTED/DISABLE_ACCOUNT_PORTAL to know which guard applies
- Point users at account.budibase.app for account-level deletion
When it happens
Trigger: destroy() called on a user whose email matches an account in the account portal, where dbUser.userId equals the current identity's _id (self-deletion attempt), in a cloud deployment (env.SELF_HOSTED false and DISABLE_ACCOUNT_PORTAL false).
Common situations: Admin API DELETE /users/self in a cloud tenant; UI actions exposing self-delete; scripts cleaning up users that accidentally include the account-holder email.
Related errors
- Account holder cannot be deleted
- Access denied to object store bucket.${err}
- Error activating license key: ${message}
- Forbidden
- Knowledge source downloads are disabled for this operation
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/77a9a5601cb7c32b.
Report an issue: GitHub.