New Users Get 2 Email Verification Emails

produkt

Feb 10th, 2025 06:22 PM

When my new users sign up, they get 2 verification emails right away instead of 1. Why is this happening? I do have email verification required in my admin setup, and I also am redirecting users to the dashboard which has the 'verified' middleware enabled, so maybe that has something to do with it? How do I avoid the user receiving 2 verification requests on signup in this situation?

bobbyiliev

Feb 10th, 2025 11:23 PM

Hi

I couldn’t reproduce this issue locally, so it might be something specific to your setup. You might want to check if any custom event listeners or duplicate calls to sendEmailVerificationNotification() are causing this.

A good way to debug it is by installing Laravel Debugbar to track what’s happening during the signup process. It should help you catch any unexpected duplicate email triggers. Let me know what you find! 🚀

produkt

Feb 11th, 2025 12:42 PM

If I do a fresh wave install and run php artisan event:list I get this:

  Illuminate\Auth\Events\Registered ....................................................  
  ⇂ Illuminate\Auth\Listeners\SendEmailVerificationNotification  

If I run php artisan event:list on my project, I get this:

  Illuminate\Auth\Events\Registered ...............................................................  
  ⇂ Illuminate\Auth\Listeners\SendEmailVerificationNotificationApp\Listeners\UserRegistered@handle  
  ⇂ Illuminate\Auth\Listeners\SendEmailVerificationNotification  

I don't really know what this means or how it happened because I didn't mess with anything of the sort. How do I fix this?

bobbyiliev

Feb 11th, 2025 12:43 PM

Yes, it seems like there are two instances of the SendEmailVerificationNotification in your project.

If you do a grep -rl SendEmailVerificationNotification * in your project where do you see it defined?

bobbyiliev

Feb 11th, 2025 12:43 PM

Yes, it seems like there are two instances of the SendEmailVerificationNotification in your project.

If you do a grep -rl SendEmailVerificationNotification * in your project where do you see it defined?

produkt

Feb 11th, 2025 12:45 PM

alex@Alexs-MBP-16 claimzap % grep -rl SendEmailVerificationNotification *
app/Providers/EventServiceProvider.php
storage/debugbar/X00dddf20a30f5dde6d4095e131b180cb.json
storage/debugbar/X9e8d307c28cda7eb37a6c4d413e2391f.json
storage/logs/laravel.log
vendor/composer/autoload_classmap.php
vendor/composer/autoload_static.php
vendor/laravel/framework/src/Illuminate/Auth/Listeners/SendEmailVerificationNotification.php
vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/EventServiceProvider.php

Which is the same as the fresh wave install except for the debugbar json. And the contents of SendEmailVerificationNotification.php and EventServiceProvider.php are identical in each install

bobbyiliev

Feb 11th, 2025 02:10 PM

Yes, but did you check the files to make sure you did not make any changes? Specificlaly the app/Providers/EventServiceProvider.php file.

produkt

Feb 11th, 2025 02:26 PM

Yes I did check, the contents are identical in the fresh install vs my project. I’m not sure how to see where this extra listener is coming from. They both show this:

<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event to listener mappings for the application.
     *
     * @var array<class-string, array<int, class-string>>
     */
    protected $listen = [
        // Registered::class => [
        //     SendEmailVerificationNotification::class,
        // ],
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Determine if events and listeners should be automatically discovered.
     *
     * @return bool
     */
    public function shouldDiscoverEvents()
    {
        return false;
    }
}
produkt

Feb 11th, 2025 06:04 PM

Does it have something to do with this? It's driving me nuts, I don't think I have the knowledge to figure this out.

https://github.com/laravel/framework/issues/50783

produkt

Feb 11th, 2025 06:17 PM

I was able to "fix" the problem, although I don't know if this is going to break something else or is the correct way to solve the issue, but I commented out App\Providers\EventServiceProvider::class, in app/config.php. Now only 1 SendEmailVerificationNotification shows up in the event list. I don't know where the other one is coming from.

bobbyiliev

Feb 12th, 2025 05:05 AM

From what you've shared, it looks like the issue is that the SendEmailVerificationNotification listener is being registered twice, once through Laravel's default event system and again through something in your setup.

Since you mentioned that commenting out App\Providers\EventServiceProvider::class in config/app.php fixed the issue, that suggests Laravel might be auto-discovering the event listeners in a way that's causing duplication.

A better approach might be to try running:

php artisan event:clear

Then, restart your queue workers (if you're running any). If that doesn’t work, check your bootstrap/cache directory—sometimes cached files cause weird issues, so clearing them with:

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

…might help.

If you still can’t pinpoint where the second registration is happening, you might want to explicitly define the event listeners instead of relying on auto-discovery. You could try adding this to EventServiceProvider.php:

protected $listen = [
    Registered::class => [
        SendEmailVerificationNotification::class,
    ],
];

And then run:

php artisan event:clear

It is hard to tell how this ended up like it without seeing the full project and all commits made. Probably best to go over your commit history and try to pin point this to a specific time and commit to see if you could find when exactly it started happening as it is not happening with a plain Wave install so it must have been caused by some of the changes you've made.

produkt

Feb 12th, 2025 07:02 AM

Wow OK, I figured it out! 😭 I was going through my commits and I discovered what happened. In bootstrap/app.php when installing my health check and integrating middleware, I changed the default of this:

$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

To this, when I tried to integrate the health check as posted in this thread (https://devdojo.com/question/health-check) and updating my middleware to allow Sanctum:

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        channels: __DIR__.'/../routes/channels.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->statefulApi();
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

I believe specifically the configure method is autoregistering some stuff. Do you know of a way I can include the health check and the Sanctum middleware of of $middleware->statefulApi(); in a way that integrates well with the original code in app.php? (Avoiding the ::configure method, or something else?)