BookStackApp/BookStack · error · UserRegistrationException

errors.auth_pre_register_theme_prevention

Error message

errors.auth_pre_register_theme_prevention

What it means

registerUser() dispatches the AUTH_PRE_REGISTER theme event, allowing custom theme code to veto registration by returning exactly false. When that happens, BookStack throws UserRegistrationException with the translated 'errors.auth_pre_register_theme_prevention' message and aborts user creation.

Source

Thrown at app/Access/RegistrationService.php:93

     */
    public function registerUser(array $userData, ?SocialAccount $socialAccount = null, bool $emailConfirmed = false): User
    {
        $userEmail = $userData['email'];
        $authSystem = $socialAccount ? $socialAccount->driver : auth()->getDefaultDriver();

        // Email restriction
        $this->ensureEmailDomainAllowed($userEmail);

        // Ensure the user does not already exist
        $alreadyUser = !is_null($this->userRepo->getByEmail($userEmail));
        if ($alreadyUser) {
            throw new UserRegistrationException(trans('errors.error_user_exists_different_creds', ['email' => $userEmail]), '/login');
        }

        /** @var ?bool $shouldRegister */
        $shouldRegister = Theme::dispatch(ThemeEvents::AUTH_PRE_REGISTER, $authSystem, $userData);
        if ($shouldRegister === false) {
            throw new UserRegistrationException(trans('errors.auth_pre_register_theme_prevention'), '/login');
        }

        // Create the user
        $newUser = $this->userRepo->createWithoutActivity($userData, $emailConfirmed);
        $newUser->attachDefaultRole();

        // Assign a social account if given
        if ($socialAccount) {
            $newUser->socialAccounts()->save($socialAccount);
        }

        Activity::add(ActivityType::AUTH_REGISTER, $socialAccount ?? $newUser);
        Theme::dispatch(ThemeEvents::AUTH_REGISTER, $authSystem, $newUser);

        // Start the email confirmation flow if required
        if ($this->emailConfirmationService->confirmationRequired() && !$emailConfirmed) {
            $newUser->save();

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Inspect your theme's AUTH_PRE_REGISTER handler (functions.php / theme code) to see why it returned false
  2. Log inputs ($authSystem, $userData) inside the handler to identify the rejected user and reason
  3. Fix the handler's logic if the rejection is unintended (e.g. domain allowlist missing the user's domain)
  4. If intentional, communicate the block to users or adjust the allowlist; ensure the handler returns true/void (not false) to allow registration

Example fix

// before (theme functions.php — vetoes everything accidentally)
Theme::listen(ThemeEvents::AUTH_PRE_REGISTER, function ($system, $data) {
    return checkAllowed($data['email']); // returns false on lookup failure
});
// after — only veto explicitly, default to allow
Theme::listen(ThemeEvents::AUTH_PRE_REGISTER, function ($system, $data) {
    if (str_ends_with($data['email'], '@blocked.example.com')) {
        return false;
    }
    return true;
});
Defensive patterns

Strategy: try-catch

Validate before calling

// Audit all theme listeners for AUTH_PRE_REGISTER and ensure they only return false deliberately:
$listeners = Theme::getListeners(ThemeEvents::AUTH_PRE_REGISTER); // if exposed
// Or grep your themes dir:
// grep -rn "AUTH_PRE_REGISTER" themes/

Try / catch

try {
    auth()->attemptOidcLogin();
} catch (BookStack\Access\Oidc\OidcException $e) {
    if (str_contains($e->getMessage(), 'auth_pre_register_theme_prevention')) {
        Log::info('Registration vetoed by theme hook', ['user' => $email]);
        return redirect('/login')->withErrors(['theme' => 'Registration was blocked by a custom policy']);
    }
    throw $e;
}

Prevention

When it happens

Trigger: registerUser() (via findOrRegister during OIDC/external login) fires Theme::dispatch(ThemeEvents::AUTH_PRE_REGISTER, $authSystem, $userData); the registered theme handler returns boolean false, causing the exception before user creation.

Common situations: A custom theme's AUTH_PRE_REGISTER hook (e.g. allowlisting domains, blocking bots, syncing to external systems) deliberately rejects the user, or the hook has a bug returning falsy/false unintentionally (e.g. returning 0, null-cast logic, or returning false from an API-check helper).

Related errors


AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02). Data as JSON: /api/errors/d3d5e0c9726ebb63. Report an issue: GitHub.