coleam00/Archon · error · APIError

Email is required.

Error message

Email is required.

What it means

Thrown from the signup createUser hook in buildAuth when the auth provider completes registration without an email address. The hook needs the email both to gate on the invite allowlist and to identify the user, so a missing email is treated as a BAD_REQUEST APIError (HTTP 400). This is a defensive check: email/password providers always supply an email, but OAuth or anonymous-style providers may create users with no email set.

Source

Thrown at packages/server/src/auth/instance.ts:123

      user: {
        create: {
          before: async (
            user: User & Record<string, unknown>
          ): Promise<{ data: User & Record<string, unknown> }> => {
            // Defense in depth: `disableSignUp` (set above from getSignupMode)
            // already blocks registration in `disabled` mode before this hook
            // runs — re-check here so the hook stays correct on its own if that
            // upstream enforcement ever changes.
            if (signupDisabled) {
              throw new APIError('FORBIDDEN', { message: 'Signup is disabled.' });
            }
            // Invite gate (`allowlist` mode): reject signups whose email is not on
            // the allowlist. Throwing APIError surfaces a clean 403 instead of a
            // generic 500. An empty allowlist makes isEmailAllowed() return true,
            // so this hook is a no-op in `open` mode — `disableSignUp` and the
            // posture above are what actually govern whether signup is permitted.
            if (!user.email) {
              throw new APIError('BAD_REQUEST', { message: 'Email is required.' });
            }
            if (!isEmailAllowed(user.email, allowedEmails)) {
              throw new APIError('FORBIDDEN', {
                message: 'This email is not on the invite allowlist.',
              });
            }
            return { data: user };
          },
        },
      },
    },
  });
}

/**
 * Release the Better Auth pg.Pool on graceful shutdown. No-op when web auth is
 * disabled (no pool was ever created).
 */

View on GitHub (pinned to 0773b97458)

Solutions

  1. Configure the OAuth provider to request the `email`/`user:email` scope so the returned profile includes an email.
  2. If using an anonymous or no-email auth path, disable it or switch to an email-bearing provider, since this instance requires emails.
  3. Have the user set/verify a primary email on their provider account before signing in.
  4. If client-side, ensure the signup request payload includes a valid `email` field.

Example fix

// before: OAuth provider config without email scope
scopes: ["read:user"]
// after: request email access
scopes: ["read:user", "user:email"]
Defensive patterns

Strategy: validation

Validate before calling

function hasEmail(profile: { email?: string | null }): profile is { email: string } {
  return typeof profile.email === 'string' && profile.email.includes('@');
}
if (!hasEmail(oauthProfile)) {
  // prompt for email manually or block signup before calling the API
}

Type guard

function isSignableUser(u: { email?: string | null }): u is { email: string } {
  return typeof u.email === 'string' && u.email.length > 0;
}

Try / catch

try {
  await authClient.signUp.email({ email, password, name });
} catch (e) {
  if (e?.status === 400 && /email is required/i.test(e?.message ?? '')) {
    promptUserForEmail();
  } else throw e;
}

Prevention

When it happens

Trigger: A signup flow (typically an OAuth/social login provider that doesn't return an email scope, or an anonymous signup path) invokes the createUser hook with a `user` object whose `email` field is null or undefined.

Common situations: Configuring a GitHub/Google OAuth provider without requesting the `email` scope; a user whose provider account has no verified primary email and no fallback; enabling an anonymous-credentials provider alongside the allowlist gate; calling the signup API directly with a payload lacking email.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/81734a5c044baf7a. Report an issue: GitHub.