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
- Configure the OAuth provider to request the `email`/`user:email` scope so the returned profile includes an email.
- If using an anonymous or no-email auth path, disable it or switch to an email-bearing provider, since this instance requires emails.
- Have the user set/verify a primary email on their provider account before signing in.
- 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
- Always request the email scope when configuring OAuth providers.
- Test each configured provider's returned profile for a non-empty email.
- Disable anonymous/no-email credential providers on instances that gate by email.
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
- OpenAI token ${operation} response missing access_token/expi
- OpenAI token ${operation} response missing refresh_token.
- OpenAI token ${operation} response did not include an id_tok
- Failed to extract the ChatGPT account id from the OpenAI acc
- Stored OpenAI credential has no refresh token.
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/81734a5c044baf7a.
Report an issue: GitHub.