Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

strmizo's avatar

L5 Maximum function nesting level of '100' reached, aborting!

Hello guys ! I have an EmailNotifierInterface, and a class EmailNotifier that implements that interface, and it depends on Mailer Contract from 'Illuminate\Contracts\Mail\Mailer'

and this EmailNotifierInterface injected an Event Handler.

but it gives me this error

Maximum function nesting level of '100' reached, aborting!

Code

<?php
namespace App\Services;

interface EmailNotifierInterface
{
    /**
     * Sends a confirmation email to user just registred
     *
     * @param $email
     * @param $confirmationKey
     */
    public function sendRegistrationConfirmation($email, $confirmationKey);
}

<?php
namespace App\Services;

use Illuminate\Contracts\Mail\Mailer;

class EmailNotifier implements EmailNotifierInterface
{


    /**
     * @var Mailer
     */
    private $mailer;

    function __construct(Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    /**
     * Sends a confirmation email to user just registred
     *
     * @param $email
     * @param $confirmationKey
     */
    public function sendRegistrationConfirmation($email, $confirmationKey){


        $data = ['email' => $email,'confirmationKey' => $confirmationKey];


        $this->mailer->send('email.confirmation', $data,  function($message) use($email){

                $message->to($email)->subject(trans("emails.title_confirmation_email"));

        });
    }
}

<?php namespace App\Handlers\Events;

use App\Events\UserWasRegistred;

use App\Services\EmailNotifier;
use App\Services\EmailNotifierInterface;
use Illuminate\Mail\Mailer;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;

class SendConfirmationEmail {
    /**
     * @var EmailNotifierInterface
     */
    private $emailNotifier;

    /**
     * Create the event handler.
     *
     * @return void
     */
    public function __construct(EmailNotifierInterface $mailer)
    {

        $this->emailNotifier = $mailer;

    }

    /**
     * Handle the event.
     *
     * @param  UserWasRegistred  $event
     * @return void
     */
    public function handle(UserWasRegistred $event)
    {


        $confirmationKey = $this->generateConfirmationKey();

        $this->emailNotifier->sendRegistrationConfirmation($event->getUser()->email, $confirmationKey);

    }

// In AppServiceProvider
    $this->app->bind(
            'App\Services\EmailNotifierInterface',
            'App\Services\EmailNotifier');


// and this is the Error !

Whoops, looks like something went wrong.

1/1
FatalErrorException in ClassLoader.php line 321:
Maximum function nesting level of '100' reached, aborting!
in ClassLoader.php line 321
at HandleExceptions->fatalExceptionFromError(array('type' => '1', 'message' => 'Maximum function nesting level of '100' reached, aborting!', 'file' => '/Applications/MAMP/htdocs/chhiwty/vendor/composer/ClassLoader.php', 'line' => '321')) in HandleExceptions.php line 116
at HandleExceptions->handleShutdown()

0 likes
65 replies
strmizo's avatar

Thank you l'3achiir :D It worked i had to move up the limit to 300, but i still didn't know that causes this recursive calling !! Peace !!

xirkus's avatar

Did you ever figure out the issue? I too am getting this error and when do exactly what you were doing - i.e. sending an email as a Handler Event.

xirkus's avatar

@rogierverbrugge Thanks for the reply. Yes, I've implemented that fix and it works, but I am more curious about the cause. It seems like a hell of a lot of work going on for a simple action.

pmall's avatar

You shouldnt have to modify this setting, someone has to find this bug :-D

1 like
xirkus's avatar

Or even just explain what the "bug" is!

rajankarthiks's avatar

@JeffreyWay Can you please guide us whats going on there.. Even I found the same issue at same place ie) when trying to send a email from event handler.

IsraelOrtuno's avatar

This has just happened to me when using codeception. I had to go to my homestead machine and edit /etc/php5/conf.d/xdebug.ini adding this xdebug.max_nesting_level=300

Viking's avatar

@jaradlight , yes i know what you mean , and me too want to have a better inside in this error .

If i use a clean install ... make a command, and inside a command i use a event to send a mail, i get the same error...

robmazur's avatar

I started getting that error just after adding Clockwork middleware. As soon as I commented it out from Kernel.php the error went away.

1 like
creativeorange's avatar

Did anyone of you guys report an official bug report? I'm not actually sure what the problem is, Laravel, SwiftMailer, Composer or Symphony.

bobbybouwmann's avatar

@rodzzlessa The solution is to update the xdebug.max_nesting_level=100 to xdebug.max_nesting_level=300 or xdebug.max_nesting_level=500

creativeorange's avatar

@blackbird I don't think this is a solution. The way I see it, changing the max_nesting_level is like saying: Hey, I know the code is a little buggy, so try 200 extra times, maybe it'll work then. And this is not even my main concern. On local development, you have total control over your environment. But what if you develop an application for a client and they will install it on their own server? You want your application to work out-of-the-box, without changing any settings (if possible). It seems this is a bug which can be fixed, therefore I think someone should take a look at it instead of asking everyone to change their settings.

5 likes
afrayedknot's avatar

I have this bug - but only when running PHPUnit.

If I do this it works in testing + normally:

<?php namespace App\Mail;

use Mail;
use App\User;

class MyMail
{

    public function sendWelcomeEmail(User $user)
    {
        $data['user'] = $user;
        $data['email_to'] = $user->email;
        $data['email_name'] = $user->name;
        $data['email_type'] = 'auth.welcome';
        $data['email_subject'] = 'Welcome';

        Mail::queue('emails.'.$data['email_type'], $data, function ($message) use ($data) {
            $message->to($data['email_to'], $data['email_name'])->subject($data['email_subject']);
        });
    }
}

BUT if I change the code, and move the mail::queue() into its own function - the error appears (only in testing - works normally):

<?php namespace App\Mail;

use Mail;
use App\User;

class MyMail
{

    public function sendWelcomeEmail(User $user)
    {
        $data['user'] = $user;
        $data['email_to'] = $user->email;
        $data['email_name'] = $user->name;
        $data['email_type'] = 'auth.welcome';
        $data['email_subject'] = 'Welcome';

        $this->sendEmail($data);
    }

    public function sendEmail($data)
    {
        return Mail::queue('emails.'.$data['email_type'], $data, function ($message) use ($data) {
            $message->to($data['email_to'], $data['email_name'])->subject($data['email_subject']);
        });
    }
}

Its really strange - because that code change should have no effect - yet it does!

larryweya's avatar

For me, it only happens when the code I'm testing is calling the Mailer. I'm getting around it in tests by mocking the call to the mailer

\Mail::shouldReceive('queue')->once();
StormShadow's avatar

Getting same error here, calling mailer from an event handler. I noticed couple of weird things. 1) When I test my route in PHPUnit, It sucessfully sends my mail to the log (mail log driver enabled), but when I try AJAX in the browser I am getting 500. 2) Also my xdebug.max_nesting_level is ALREADY AT 500! I logged all the parameters passed to Mail and they all are OK, so like you guys, I am seriously stuck!

StormShadow's avatar

Folks is there any way we could escalate this to the attention of the Laravel team? Seems like they would be alarmed if we cant send email at all! This is the first time I ran into what may be a framework issue. Also, from what everyone is saying on this thread the bug seems easily reproducible.

StormShadow's avatar

If I call the method that sends the email directly in contoller it works. But I wanted to use Command, which fires an event that would send the email. However, this clearly doesn't work.

This works, but isn't ideal

  class RegistrationController extends Controller {

     public function register(RegistrationRequest $registrationRequest, UserMailer $mailer)
    {
        $user = $this->dispatchFrom(RegistrationCommand::class, $registrationRequest);
        $mailer->sendConfirmation($user);
        $message = view('app.registration-message', compact('user'))->render();
        return response()->json(['success' => true, 'message' => $message]);
    } 
}

This won't work :

class RegistrationCommandHandler {

    protected $repository;

    public function __construct(UserRepository $repository)
{
        $this->repository = $repository;
    }

    public function handle(RegistrationCommand $command)
    {
        $user = new User();
        $user->first_name = $command->first_name;
        $user->last_name = $command->last_name;
        $user->email = $command->email;
        $user->password = bcrypt($command->password);
        $user->user_type = $command->user_type;
        $user->confirmed = 0;
        $user->confirmation = str_random(40);
        $this->repository->save($user);
        event(new UserHasRegistered($user)); 
        return $user;
}
}

class UserEventHandler {

    protected $userMailer;

    function __construct(UserMailer $userMailer)
    {
        $this->userMailer = $userMailer;
    }

    public function onUserHasRegistered(UserHasRegistered $event)
    {
        $this->userMailer->sendConfirmation($event->user);
    }

    public function subscribe($events)
    {
        $events->listen(UserHasRegistered::class, 'App\Handlers\Events\UserEventHandler@onUserHasRegistered');
    }
}

And yes, the listener is registered properly.

jekinney's avatar

I get that error when I try to grab one row (first()) but instead I put get() at the end of the query which returns the error. It's basically your getting the wrong type error.

StormShadow's avatar

Guys what I did to get my code working was edit the file /etc/php5/fpm/conf.d/20-xdebug.ini in homestead with xdebug.max_nesting_level = 500 then sudo service nginx restart and sudo service php5-fpm restart

I don't think this is a recursion, simply the number of method calls in a row exceeds the default of 100. Looks like Taylor now puts a default of 250 https://github.com/laravel/settler/blob/master/scripts/provision.sh#L127

Curious if this edit would be necessary on a Forge server.

All is working now! No need to alert the Laravel brass lol!

1 like
oes's avatar

@StormShadow I had this issue a month or so ago. My issue was moving from Facades to contracts in a few places with the same code. I had to increase my level to 120. So I know it could not have been a recursion issue as it would just keep exceeding the nesting level. I had to increase the production server on Forge to 120 as well.

Pretty glad to see Taylor has increased the level, I have seen more people with this issue on IRC and Slack with L5.

opheliadesign's avatar

I ran into this today, too. Homestead, box is up to date, Laravel 5. Trying to send email form a Command. It works in production (Digital Ocean / Forge), works on one dev computer but not the other - possibly sporadic?

I'm a bit confused as to the final conclusion on this - bug? Can't send email from a Command? Unless I missed something, this thread shows how to hack things so that the app might not crash - how to stop the recursion??

This is my second headache with Laravel 5 Commands. Beanstalkd refuses to work in production and nobody can tell me why, including Taylor (so far, hopefully he can find out more) and now this. Trying not to be frustrated, but I'm losing hours of time troubleshooting this.

Next

Please or to participate in this conversation.