gitroomhq/postiz-app · warning · Error
Account is already activated
Error message
Account is already activated
What it means
Thrown by resendActivationEmail when the target user record already has its 'activated' flag set. The service refuses to generate and send a new activation JWT for an account that no longer needs one. This is a domain-state guard, not a bug indicator.
Source
Thrown at apps/backend/src/services/auth/auth.service.ts:276
await this._userService.activateUser(user.id);
user.activated = true;
this._track('register', user.email, tracking).catch((err) => {});
await NewsletterService.register(user.email);
return this.jwt(user as any);
}
return false;
}
async resendActivationEmail(email: string) {
const user = await this._userService.getUserByEmail(email);
if (!user) {
throw new Error('User not found');
}
if (user.activated) {
throw new Error('Account is already activated');
}
const jwt = await this.jwt(user);
await this._emailService.sendEmail(
user.email,
'Activate your account',
`Click <a href="${process.env.FRONTEND_URL}/auth/activate/${jwt}">here</a> to activate your account`,
'top'
);
return true;
}
oauthLink(provider: string, query?: any) {
const providerInstance = this._providerManager.getProvider(provider);
return providerInstance.generateLink(query);
}View on GitHub (pinned to 0f1647f749)
Solutions
- Confirm the user actually needs activation (check the activated column) before calling the endpoint
- Have the frontend refresh user state after activation and hide the 'resend email' button
- Treat this error as a 200-level 'nothing to do' case in the controller / UI instead of showing a failure
- Audit for accidental re-use of the resend flow as a login trigger
Example fix
// before
await authService.resendActivationEmail(user.email);
// after
const user = await userService.getUserByEmail(email);
if (user?.activated) {
return { alreadyActivated: true };
}
await authService.resendActivationEmail(email); Defensive patterns
Strategy: validation
Validate before calling
const user = await userService.getUserByEmail(email);
if (!user || user.activated) {
// nothing to send
return { ok: true, alreadyActivated: Boolean(user?.activated) };
}
await authService.resendActivationEmail(email); Type guard
const isUnactivatedUser = (u: User | null): u is User & { activated: false } =>
!!u && typeof u.activated === 'boolean' && !u.activated; Try / catch
try {
await authService.resendActivationEmail(email);
} catch (e) {
if (e instanceof Error && e.message === 'Account is already activated') return { ok: true };
throw e;
} Prevention
- Refresh user state after activation completes before showing resend UI
- Disable the resend button once activation succeeds
When it happens
Trigger: Calling the resend-activation endpoint with the email/identifier of a user whose `user.activated` is true in the database (e.g. POST /auth/resend-activation after the user already clicked the activation link).
Common situations: User double-clicks the resend button after activating in another tab; frontend keeps a stale 'not activated' state; testing with a seed account that is already activated.
Related errors
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/06952098722d8a67.
Report an issue: GitHub.