calcom/cal.diy · error · BadRequestException

Email and code are required

Error message

Email and code are required

What it means

Thrown by VerificationAtomService.verifyEmailCodeUnAuthenticated when the upstream rejects with an Error whose message equals 'BAD_REQUEST', surfaced as a 400 'Email and code are required'. The intent is to flag a missing-email-or-code call. IMPORTANT: this branch is DEAD under current source — verifyCodeUnAuthenticated throws new Error('Email and code are required') (not 'BAD_REQUEST'), so the equality check never matches and execution falls through to the generic 'Verification failed' (error 22). Callers therefore never see this specific message today.

Source

Thrown at apps/api/v2/src/modules/atoms/services/verification-atom.service.ts:37

  constructor(
    private readonly atomsSecondaryEmailsRepository: AtomsSecondaryEmailsRepository,
    private readonly usersRepository: UsersRepository
  ) {}

  async checkEmailVerificationRequired(input: CheckEmailVerificationRequiredParams) {
    return await checkEmailVerificationRequired(input);
  }

  async verifyEmailCodeUnAuthenticated(input: VerifyEmailCodeInput) {
    try {
      return await verifyCodeUnAuthenticated(input.email, input.code);
    } catch (error) {
      if (error instanceof Error) {
        if (error.message === "invalid_code") {
          throw new BadRequestException("Invalid verification code");
        }
        if (error.message === "BAD_REQUEST") {
          throw new BadRequestException("Email and code are required");
        }
      }
      throw new BadRequestException("Verification failed");
    }
  }

  async verifyEmailCodeAuthenticated(user: UserWithProfile, input: VerifyEmailCodeInput) {
    try {
      return await verifyCodeAuthenticated({
        user,
        email: input.email,
        code: input.code,
      });
    } catch (error) {
      if (error instanceof Error) {
        if (error.message === "invalid_code") {
          throw new BadRequestException("Invalid verification code");
        }

View on GitHub (pinned to 176037d0af)

Solutions

  1. As platform maintainer: fix the predicate to match the actual upstream message 'Email and code are required', or better, validate input shape (class-validator DTO) before calling the upstream so missing fields never reach the try/catch.
  2. As API caller: ensure the request body includes both non-empty email and code fields before sending.
  3. Add a DTO-level @IsNotEmpty()/@IsString() guard on VerifyEmailCodeInput so this is a 422 before the service layer.

Example fix

// before
if (error.message === "BAD_REQUEST") {
  throw new BadRequestException("Email and code are required");
}

// after
if (error.message === "Email and code are required" || error.message === "BAD_REQUEST") {
  throw new BadRequestException("Email and code are required");
}
Defensive patterns

Strategy: validation

Validate before calling

if (!input?.email || !input?.code) {
  throw new BadRequestException('Email and code are required');
}

Type guard

function hasEmailAndCode(v: unknown): v is { email: string; code: string } {
  return typeof v === 'object' && v !== null &&
    typeof (v as any).email === 'string' && (v as any).email.length > 0 &&
    typeof (v as any).code === 'string' && (v as any).code.length > 0;
}

Prevention

When it happens

Trigger: POST to the unauthenticated verify endpoint with email or code omitted/empty, AND the upstream library throwing an Error whose message is literally 'BAD_REQUEST'. The real upstream message is 'Email and code are required', so the predicate misses.

Common situations: Client omits the code field; client sends an empty string; client sends null; contract drift after upgrading @calcom/features/auth where the thrown message string changed.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/57f327ecf0dbc683. Report an issue: GitHub.