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

idcreatv's avatar

'No scheduled commands are ready to run' when command is set to run every minute

Following on from an earlier thread, I have a command which currently runs every minute (will be daily once development is complete) to check if any courses are running today and, if so, send a reminder email:

$schedule->command('dailyCourse:reminder')->everyMinute();

My earlier problem was with SwiftMailer (composer update seemed to do the trick) and when I ran my command it fired off the email. I stopped the command and tidied up my testing code (removed info() logging etc) and when I ran my command again…

php artisan schedule:work

…my console log said:

[2022-09-13T08:27:00+01:00] Execution #1 output:
No scheduled commands are ready to run.

So, why would it ignore the command since its set to run each minute, and how would I fix it?

Here's my command code:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use Carbon\Carbon;
use Mail;

use App\Models\Course;
use App\Models\Coursesettings;
use App\Mail\GenericEmail;

class DailyCourseReminder extends Command
{
  /**
   * The name and signature of the console command.
   *
   * @var string
   */
  protected $signature = 'dailyCourse:reminder';

  /**
   * The console command description.
   *
   * @var string
   */
  protected $description = 'Command description';

  /**
   * Create a new command instance.
   *
   * @return void
   */
  public function __construct()
  {
    parent::__construct();
  }

  /**
   * Execute the console command.
   *
   * @return int
   */
  public function handle()
  {
    $email_recipients = [];
    $courses = Course::with('bookings')->where('start_date', Carbon::today())->get();
    foreach ($courses as $course) {
      $bookings = $course->bookings;
      // Grab the bookings
      foreach ($bookings as $booking) {
        // Grab the attendees
        foreach (json_decode($booking->attendees) as $attendee) {
          $email = $attendee->email;
          if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            array_push($email_recipients, $email);
          }
        }
      }
    }
    // Send the emails
    if ($email_recipients != null) {
      // Grab the Coursesettings key => value pairs
      $settings = Coursesettings::orderby('key', 'asc')
      ->where('key', 'email_attendee_booking_confirmation')
      ->pluck('value', 'key')->toArray();
      // Course type
      if ($course->type == 0) {
        $course_type = 'physical';
      } else {
        $course_type = 'virtual';
      }
      // Set subject
      $subject = 'Reminder: You are enrolled on a course for today';
      // Intro text
      $intro_text = 'Hello, this email is to remind you that you are booked on the following course for today:';
      // Message
      $message_body = $settings['email_attendee_booking_confirmation'];
      // Shortcodes to change
      $message_body = str_replace('[COURSENAME_HERE]', $course->coursename->name, $message_body);
      $message_body = str_replace('[STARTDATE_HERE]', Carbon::parse($course->start_date)->format('d/m/Y'), $message_body);
      $message_body = str_replace('[STARTTIME_HERE]', $course->start_time, $message_body);
      $message_body = str_replace('[ENDTIME_HERE]', $course->end_time, $message_body);
      $message_body = str_replace('[COURSETYPE_HERE]', $course_type, $message_body);

      $message = [
       'intro' => $intro_text,
       'message_body' => $message_body,
       'show_panel' => 'no',
       'panel_body' => 'PANEL_BODY',
       'show_button' => 'no',
       'button_label' => 'BUTTON_LABEL',
       'button_url' => url(''),
       ];

      Mail::to($email_recipients)
       ->send(new GenericEmail($message, $subject)); // End of attendee email
    // info($email_recipients);
    }
  }
}
0 likes
14 replies
idcreatv's avatar

I'm wondering if its tasks overlapping?

Sinnbeck's avatar

@idcreatv Lets start with getting it working first. Can you show Console/Kernel.php ?

idcreatv's avatar

@Sinnbeck Sure, here you go…

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
        'App\Console\Commands\DailyCourseReminder'
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('dailyCourse:reminder')
        ->everyMinute()
          ->timezone('Europe/London')
          ->withoutOverlapping();
        // $schedule->command('dailyCourse:reminder')->daily()->at('07:00')->timezone('Europe/London');
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@idcreatv what version of laravel is this?

I just tested your command (just added return 0 at the start of handle() as I dont have the rest of your logic) and it worked fine

2022-09-13 08:06:00 Running ['artisan' dailyCourse:reminder] .......................................................................... 132ms DONE

Sinnbeck's avatar

btw. The commands() method autoloads all your commands, so you can remove this

protected $commands = [
        //
        'App\Console\Commands\DailyCourseReminder'
    ];
1 like
idcreatv's avatar

@Sinnbeck Very strange, I've removed all my course emailer code…

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use Carbon\Carbon;
use Mail;

use App\Models\Course;
use App\Models\Coursesettings;
use App\Mail\GenericEmail;

class DailyCourseReminder extends Command
{
  /**
   * The name and signature of the console command.
   *
   * @var string
   */
  protected $signature = 'dailyCourse:reminder';

  /**
   * The console command description.
   *
   * @var string
   */
  protected $description = 'Command description';

  /**
   * Create a new command instance.
   *
   * @return void
   */
  public function __construct()
  {
    parent::__construct();
  }

  /**
   * Execute the console command.
   *
   * @return int
   */
  public function handle()
  {
    info('Completed');
    return 0;
    }
  }
}

…and replaced with info('completed'); return 0; and I get…

[2022-09-13T09:10:00+01:00] Execution #1 output:
No scheduled commands are ready to run.

When I check my log file, I'm not even getting 'Completed' - its completely empty. :\

I've also removed ''App\Console\Commands\DailyCourseReminder'' as you recommended and cleared all caches:


php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan config:cache
php artisan optimize:clear

Strange it worked once and then not again…

Sinnbeck's avatar

@idcreatv Are you sure you are running php artisan schedule:work in the correct project?

idcreatv's avatar

@Sinnbeck Yep, definitely the correct directory. I'll reboot the server and see if that fixes anything.

idcreatv's avatar

@Sinnbeck I have a VPS for development (rather than local) as its the exact same setup as that for several other clients so solving this issue should reduce the chances of it happening on theirs.

idcreatv's avatar

@Sinnbeck Okay, the server reboot seems to have solved the problem with it not firing, emails are sending now and there's no errors.

Thanks so much for all your help, its very much appreciated! :)

Snapey's avatar

if you script crashed earlier, it can leave the mutex behind. Run artisan cache:clear and also check you are not in maintenance mode

1 like

Please or to participate in this conversation.