Laravel’s event system is one of the framework’s most powerful features. However, there is a subtle issue that can cause your event listeners to execute twice when you manually define listener execution order in your EventServiceProvider.

If you’ve ever noticed duplicate emails, repeated notifications, or the same logic running twice, this might be the reason.

# The Problem

Laravel automatically discovers event listeners when event discovery is enabled. At the same time, many developers manually register listeners inside the EventServiceProvider to control the order in which listeners are executed.For example:

PHP
protected $listen = [
       UserRegistered::class => [
           SendWelcomeEmail::class,
           CreateUserProfile::class
       ]
];

When Laravel discovers listeners automatically and also finds them through type-hinting, the same listener may end up being registered twice.

The result? The listener executes twice for a single event dispatch.

# Why Does It Happen?

Consider the following listener:

PHP
class SendWelcomeEmail {
    public function handle(UserRegistered $event): void {
        // Send email
    }
}

Because the handle() method type-hints the event, Laravel’s event discovery mechanism can automatically associate this listener with the event.

If you additionally register the listener manually to control execution order, Laravel may register it twice.

# The Solution

When manually defining listener order, remove the event type hint from the listener’s handle() method.

PHP
public function handle($event): void {
     //
}

This prevents Laravel’s event discovery mechanism from automatically discovering the listener while still allowing the listener to receive the event instance.

# When Should You Do This?

Consider removing the type hint when:

  • You manually register listeners in EventServiceProvider.
  • You need strict execution order between multiple listeners.
  • Event discovery is enabled in your application.
  • You notice listeners being executed twice.