fullstackhero/dotnet-starter-kit · warning · CustomException

Users cannot deactivate themselves.

Error message

Users cannot deactivate themselves.

What it means

UserStatusService.ValidateTogglePermissionsAsync throws CustomException with 400 BadRequest ("Users cannot deactivate themselves.") when an admin attempts to toggle their own account to inactive. Self-deactivation is blocked because it would lock the actor out mid-session; the policy failure is audited first as SelfDeactivationBlocked.

Solutions

  1. Have another administrator perform the deactivation.
  2. Exclude the current user's id from bulk deactivation lists.
  3. If the account must be disabled, use a second admin account.
  4. Update the UI to hide/disable the deactivate action for the logged-in user.

Example fix

// before
await mediator.Send(new ToggleUserStatusCommand { UserId = currentUserId, ActivateUser = false });
// after
if (targetId != currentUserId)
    await mediator.Send(new ToggleUserStatusCommand { UserId = targetId, ActivateUser = false });
Defensive patterns

Strategy: validation

Validate before calling

if (command.UserId == currentUserId && !command.ActivateUser)
    return Result.BadRequest("You cannot deactivate your own account.");

Try / catch

try { ... }
catch (CustomException) { showBanner("Self-deactivation is not allowed; ask another admin."); }

Prevention

When it happens

Trigger: An administrator invoking toggle-status with their own userId and activateUser=false; scripting bulk deactivations that include the acting admin's id.

Common situations: Admins trying to 'test' deactivation on themselves; bulk scripts iterating all users including the operator; UIs not filtering out the current user from deactivation lists.

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 fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15). Data as JSON: /api/errors/7036b486b6856704. Report an issue: GitHub.

Appendix: source

Thrown at src/Modules/Identity/Modules.Identity/Services/UserStatusService.cs:87

            TargetUser: targetUser,
            ActivateUser: activateUser,
            TenantId: multiTenantContextAccessor?.MultiTenantContext?.TenantInfo?.Id);
    }

    private async Task ValidateTogglePermissionsAsync(
        ToggleStatusContext context,
        CancellationToken cancellationToken)
    {
        if (!await userManager.IsInRoleAsync(context.Actor, RoleConstants.Admin))
        {
            await AuditPolicyFailureAsync(context, "ActorNotAdmin", cancellationToken);
            throw new ForbiddenException("Only administrators can change user status.");
        }

        if (!context.ActivateUser && context.ActorId.ToString() == context.TargetUser.Id)
        {
            await AuditPolicyFailureAsync(context, "SelfDeactivationBlocked", cancellationToken);
            throw new CustomException("Users cannot deactivate themselves.", Array.Empty<string>(), HttpStatusCode.BadRequest);
        }

        if (!context.ActivateUser && await userManager.IsInRoleAsync(context.TargetUser, RoleConstants.Admin))
        {
            await AuditPolicyFailureAsync(context, "AdminDeactivationBlocked", cancellationToken);
            throw new CustomException("Administrators cannot be deactivated.", Array.Empty<string>(), HttpStatusCode.BadRequest);
        }

        if (!context.ActivateUser)
        {
            await EnsureMinimumActiveAdminsAsync(context, cancellationToken);
        }
    }

    private async Task EnsureMinimumActiveAdminsAsync(
        ToggleStatusContext context,
        CancellationToken cancellationToken)
    {

View on GitHub (pinned to 3f2959e683)