calcom/cal.diy · error · BadRequestException
Email already exists
Error message
Email already exists
What it means
BadRequestException('Email already exists') from VerificationAtomService when adding a secondary email. It fires when atomsSecondaryEmailsRepository.getExistingSecondaryEmail(email) finds that the supplied email is already registered as a secondary email anywhere in the system — preventing duplicate email ownership across accounts. This is a real, live business-rule guard (unlike 20-25).
Source
Thrown at apps/api/v2/src/modules/atoms/services/verification-atom.service.ts:122
return verifiedEmails;
}
async addVerifiedEmail({
userId,
existingPrimaryEmail,
email,
}: {
userId: number;
existingPrimaryEmail: string;
email: string;
}): Promise<boolean> {
const existingSecondaryEmail =
await this.atomsSecondaryEmailsRepository.getExistingSecondaryEmailByUserAndEmail(userId, email);
const alreadyExistingEmail = await this.atomsSecondaryEmailsRepository.getExistingSecondaryEmail(email);
if (alreadyExistingEmail) {
throw new BadRequestException("Email already exists");
}
if (existingPrimaryEmail === email || existingSecondaryEmail === email) {
return true;
}
await this.atomsSecondaryEmailsRepository.addSecondaryEmailVerified(userId, email);
return true;
}
removeClientIdFromEmail(email: string): string {
const [localPart, domain] = email.split("@");
const localPartSegments = localPart.split("+");
localPartSegments.pop();
const baseEmail = localPartSegments.join("+");View on GitHub (pinned to 176037d0af)
Solutions
- Tell the end user to choose a different email, or to remove the secondary email from the other account first.
- If you believe this is stale data, inspect atoms_secondary_emails for the email and confirm whether the owning user still claims it.
- Verify the request isn't accidentally re-submitting the user's already-owned secondary email via the global lookup (the own-email check is separate at line 130).
Defensive patterns
Strategy: validation
Validate before calling
// Before offering 'add secondary email', check it isn't already taken globally
const existing = await atomsSecondaryEmailsRepository.getExistingSecondaryEmail(email);
if (existing) {
throw new BadRequestException('Email already exists');
} Try / catch
try {
await service.addSecondaryEmail({ userId, existingPrimaryEmail, email });
} catch (e) {
if (e instanceof BadRequestException && e.message === 'Email already exists') {
// prompt user for a different email
}
throw e;
} Prevention
- Run a pre-flight availability check before sending the verification code to avoid wasted email sends.
- Normalize/trim/lowercase the email before lookup so casing doesn't bypass the duplicate check.
When it happens
Trigger: POST to add a secondary email (atoms flow) with an email that already exists in the atoms_secondary_emails table for any user. Note: only the global secondary-email lookup triggers this; the user's own primary/secondary emails take the early-return path at line 130 (existingPrimaryEmail === email || existingSecondaryEmail === email).
Common situations: User tries to add an email they already registered as secondary on another account; email was freed from another account but the row still exists; test fixtures seed duplicate emails; user mistakes another account's email for their own.
Related errors
- Invalid verification code
- Email and code are required
- Verification failed
- Email, code, and user ID are required
- ${err.message}
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/ec072e44811ad6aa.
Report an issue: GitHub.