toeverything/AFFiNE · warning · InvalidEmail

invalid_email

invalid_email

Error message

An invalid email provided: ${email}

What it means

Thrown by assertValidEmail() when zod's string().email() schema fails to parse the given email. The validator is the single chokepoint used across auth/invitation flows to reject malformed email addresses before they reach the database or email-sending layer.

Source

Thrown at packages/backend/server/src/core/utils/validators.ts:8

import z from 'zod';

import { InvalidEmail, InvalidPasswordLength } from '../../base';

export function assertValidEmail(email: string) {
  const result = z.string().email().safeParse(email);
  if (!result.success) {
    throw new InvalidEmail({ email });
  }
}

export function assertValidPassword(
  password: string,
  { min, max }: { min: number; max: number }
) {
  const result = z.string().min(min).max(max).safeParse(password);

  if (!result.success) {
    throw new InvalidPasswordLength({ min, max });
  }
}

export const validators = {
  assertValidEmail,
  assertValidPassword,
};

View on GitHub (pinned to 26c515e050)

Solutions

  1. Validate the email client-side (HTML5 input type=email + format check) before submitting.
  2. Trim whitespace from the input before calling assertValidEmail.
  3. Surface the field-level error to the user and re-prompt.

Example fix

// before
assertValidEmail(raw);

// after
assertValidEmail(raw.trim());
Defensive patterns

Strategy: validation

Validate before calling

const trimmed = email.trim();
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmed)) { showEmailError(); return; }

Type guard

function isPlausibleEmail(value: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
}

Try / catch

try {
  assertValidEmail(email);
} catch (e) {
  if (e?.code === 'invalid_email') { showFieldError('email'); return; }
  throw e;
}

Prevention

When it happens

Trigger: assertValidEmail(value) is called with a value that is not a valid RFC-style email (missing '@', invalid domain, stray characters, empty string).

Common situations: User typo in a sign-up/invite form; whitespace or trailing characters pasted from a clipboard; non-string input coerced to garbage; test fixture with a placeholder email.

Related errors


AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12). Data as JSON: /api/errors/8ec8b23f6df01073. Report an issue: GitHub.