flarum/framework · error · DomainException
Cannot delete the root admin
Error message
Cannot delete the root admin
What it means
The User model's boot() registers a `deleting` hook that throws a DomainException when the user being deleted has id 1, protecting the root admin account from deletion. This is a hard business rule of the forum: exactly one seeded super-admin must always exist. Any deletion attempt (Eloquent delete(), mass delete, etc.) on that row is aborted.
Solutions
- Skip user id 1 in deletion loops/cron jobs
- Reassign or demote other admins instead of deleting the root account
- If the account data must be erased, anonymise its columns rather than deleting the row
- For fresh installs where id 1 is a mistake, rebuild the database so the intended admin is the seeded root
Example fix
// before
User::where('last_active', '<', $cutoff)->each->delete();
// after
User::where('last_active', '<', $cutoff)->where('id', '!=', 1)->each->delete(); Defensive patterns
Strategy: try-catch
Validate before calling
if ($user->id === 1) { /* skip deletion or anonymise instead */ } Try / catch
try { $user->delete(); } catch (DomainException $e) { Log::notice('Root admin deletion blocked'); continue; } Prevention
- Exclude id 1 in bulk-deletion queries and cleanup jobs
- Provide an anonymisation path for the root account
- Never rely on cascading deletes that can reach the root admin
When it happens
Trigger: Calling $user->delete() (or User::destroy(1), bulk deletes matching id 1, or cascade paths) on the user with id == 1.
Common situations: Seeders or cleanup scripts that purge inactive users including id 1; admin panel user deletion on the original admin; GDPR/erasure jobs that attempt to hard-delete every account.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15).
Data as JSON: /api/errors/b3db3fe4e3a64c86.
Report an issue: GitHub.
Appendix: source
Thrown at framework/core/src/User/User.php:162
*
* @var callable[]
*/
protected static array $passwordCheckers;
/**
* Difference from the current `last_seen` attribute value before `updateLastSeen()`
* will update the attribute on the DB. Measured in seconds.
*/
private const LAST_SEEN_UPDATE_DIFF = 180;
public static function boot()
{
parent::boot();
// Don't allow the root admin to be deleted.
static::deleting(function (self $user) {
if ($user->id == 1) {
throw new DomainException('Cannot delete the root admin');
}
$avatarPath = $user->getRawOriginal('avatar_url');
if ($avatarPath) {
resolve(AvatarUploader::class)->deleteAllVariants($avatarPath);
}
});
static::deleted(function (self $user) {
$user->raise(new Deleted($user));
Notification::whereSubject($user)->delete();
});
static::creating(function (self $user) {
$user->joined_at = Carbon::now();
View on GitHub (pinned to 4b939f6853)