coleam00/Archon · warning · APIError
This email is not on the invite allowlist.
Error message
This email is not on the invite allowlist.
What it means
Thrown from the signup createUser hook when the instance is in 'allowlist' (invite-only) signup mode and the registering user's email is not in the configured allowed-emails list. `isEmailAllowed()` returns true for an empty allowlist, so this only fires when an allowlist is actually configured. The APIError('FORBIDDEN') produces a clean 403 for the client instead of a generic 500.
Source
Thrown at packages/server/src/auth/instance.ts:126
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).
*/
export async function closeAuth(): Promise<void> {
if (authPool) {
await authPool.end();View on GitHub (pinned to 0773b97458)
Solutions
- Ask the operator to add the user's email (or their email domain) to the allowlist configuration and restart/reload.
- Verify the allowlist value matches exactly what the identity provider returns (case, plus-tags, alias vs primary address).
- If the instance should be open to everyone, switch signup mode from 'allowlist' to 'open'.
- Check server logs to confirm which email was evaluated against the allowlist to spot mismatches.
Example fix
// before ALLOWED_EMAILS=alice@example.com // after: include the user or their domain ALLOWED_EMAILS=alice@example.com,bob@example.com,@example.com
Defensive patterns
Strategy: validation
Validate before calling
// client-side pre-check when the instance exposes its mode
const { mode, allowedEmails } = await (await fetch('/api/get-signup-mode')).json();
if (mode === 'allowlist' && allowedEmails?.length && !allowedEmails.includes(email)) {
showNotice('This email is not on the invite list.');
return;
} Try / catch
try {
await authClient.signUp.email({ email, password, name });
} catch (e) {
if (e?.status === 403 && /invite allowlist/i.test(e?.message ?? '')) {
showNotice('Your email is not invited. Ask an admin to add it.');
} else throw e;
} Prevention
- Keep the allowlist in one reviewed config source and validate entries with tests.
- Normalize case when adding entries if the matcher is case-sensitive.
- Prefer domain entries (@company.com) over long individual lists.
- Tell invited users exactly which address was allowlisted.
When it happens
Trigger: Signup mode is 'allowlist', ALLOWED_EMAILS (or equivalent) is non-empty, and a user attempts registration with an email that does not match any allowlist entry (exact or domain match per isEmailAllowed).
Common situations: A user with the wrong personal email tries to join a company instance; an admin typo'd the address in the allowlist; the allowlist uses full addresses while the user signs up with an alias; emails differ in case or plus-addressing and the matcher doesn't normalize them.
Related errors
- Signup is disabled.
- Email is required.
- Repository ${owner}/${repo} not found or is private. Check r
- Authentication failed for ${owner}/${repo}. Check GITEA_TOKE
- OpenAI token ${operation} response missing access_token/expi
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/afc178fa545ff1de.
Report an issue: GitHub.