Laravel Scheduler Issue: '1/2 * * * *' Cron Expression Valid in crontab but Not in Laravel Scheduler

131 views Asked by At

I am facing a peculiar issue with Laravel Scheduler where the cron expression '1/2 * * * *' is marked as invalid, even though it works perfectly fine when added directly to the crontab. The Laravel documentation suggests that this should be a valid cron syntax, but the scheduler throws an error.

Here's the snippet from my Laravel task scheduling:

// Kernel.php
protected function schedule(Schedule $schedule)
{
    // Other scheduled tasks...

    $schedule->command('my:command')->cron('1/2 * * * *');
}

When I run the scheduler, it complains that the cron expression is not valid. However, if I add the same expression directly to my crontab, it works as expected:

# Works in crontab
1/2 * * * * /path/to/php /path/to/artisan my:command

I've also tried using a similar expression '*/2 * * * *' in Laravel, and it worked without any issues:

// Kernel.php
protected function schedule(Schedule $schedule)
{
    // Other scheduled tasks...

    $schedule->command('my:command')->cron('*/2 * * * *');
}

This suggests that the Laravel Scheduler accepts certain cron expressions but not '1/2 * * * *'. Is there something specific about Laravel Scheduler that makes certain cron expressions invalid, even though they work outside of Laravel? How can I resolve this discrepancy and successfully schedule my task with the '1/2 * * * *' expression in Laravel?

Note: Please provide solutions within the context of Laravel Scheduler, and refrain from suggesting alternatives involving direct manipulation of the crontab. My goal is to understand and resolve this issue specifically within Laravel. Thank you!

1

There are 1 answers

0
soulseekah On

The Laravel Scheduler uses the dragonmantank/cron-expression package.

As per the tests here https://github.com/dragonmantank/cron-expression/blob/master/tests/Cron/MinutesFieldTest.php#L26 the format is considered invalid.

There is no single standard, but the slash is used to add a range to the step. 1 is not a range. 1-59 is. The code looks for a valid range https://github.com/dragonmantank/cron-expression/blob/master/src/Cron/AbstractField.php#L72

What's standard? Well, https://pubs.opengroup.org/onlinepubs/007904975/utilities/crontab.html doesn't even support the / increment syntax. And the widely available Vixie Cron, that's installed on most systems these days doesn't define the syntax without a -: https://github.com/vixie/cron/blob/master/Documentation/Features.md#stepping

Code here: https://github.com/vixie/cron/blob/3ce0c3acdf086a82638818635961c70cba2b6ba7/entry.c#L628C1-L628C1

And a similar issue here: https://github.com/vixie/cron/issues/13

On my system crontab (Vixie Cron) the syntax actually gives me bad minute.

even though it works perfectly fine when added directly to the crontab

You must be running cronie: https://github.com/cronie-crond/cronie/blob/c640f4f39e5c20995e960e4b954cd0574a96c028/src/entry.c#L550

cronie syntax does allow omitting the upper range, it also has other niceties, like ~ for a random number, for example. Laravel uses a package that adheres to Vixie standards.

The author of the package sort of confirmed it in this issue https://github.com/dragonmantank/cron-expression/issues/169

Also a great read: https://en.wikipedia.org/wiki/Cron#Non-standard_characters