laravel/framework · error · LogicException

A scheduled event name is required to prevent overlapping. U

Error message

A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'.

What it means

Thrown by CallbackEvent::withoutOverlapping() (src/Illuminate/Console/Scheduling/CallbackEvent.php:141) when $this->description is unset. Overlap prevention needs a stable mutex name; CallbackEvent derives it from the description (set via name()), so a nameless closure cannot be uniquely locked.

Source

Thrown at src/Illuminate/Console/Scheduling/CallbackEvent.php:141

            return 1;
        }
    }

    /**
     * Do not allow the event to overlap each other.
     *
     * The expiration time of the underlying cache lock may be specified in minutes.
     *
     * @param  int  $expiresAt
     * @return $this
     *
     * @throws \LogicException
     */
    public function withoutOverlapping($expiresAt = 1440, $releaseOnTerminationSignals = true)
    {
        if (! isset($this->description)) {
            throw new LogicException(
                "A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'."
            );
        }

        return parent::withoutOverlapping($expiresAt, $releaseOnTerminationSignals);
    }

    /**
     * Allow the event to only run on one server for each cron expression.
     *
     * @return $this
     *
     * @throws \LogicException
     */
    public function onOneServer()
    {
        if (! isset($this->description)) {
            throw new LogicException(

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Call ->name('unique-label') before ->withoutOverlapping().
  2. Use a descriptive stable name so the mutex doesn't collide across deploys.
  3. For jobs scheduled via Schedule::job(), a name is auto-set; ensure it isn't being reset.
  4. Prefer scheduling a named command/job if you don't want to manage names manually.

Example fix

// before
$schedule->call(fn () => syncStock())
    ->everyFiveMinutes()
    ->withoutOverlapping();

// after
$schedule->call(fn () => syncStock())
    ->name('stock-sync')
    ->everyFiveMinutes()
    ->withoutOverlapping();
Defensive patterns

Strategy: validation

Validate before calling

if ($event instanceof \Illuminate\Console\Scheduling\CallbackEvent && ! isset($event->description)) {
    // call name('...') before withoutOverlapping()
}

Type guard

// pragmatic guard: ensure a name is set before overlap locking
if (! $event->getSummaryForDisplay() || $event->getSummaryForDisplay() === 'Callback') {
    $event->name('fallback-name');
}

Try / catch

try {
    $event->withoutOverlapping();
} catch (\LogicException $e) {
    $event->name('auto-' . uniqid())->withoutOverlapping();
}

Prevention

When it happens

Trigger: Calling $schedule->call(fn ())->hourly()->withoutOverlapping() without first calling ->name('...'). Same for Schedule::job()/call() events that lack a name.

Common situations: Developers add withoutOverlapping() to a closure-based task assuming Laravel auto-names it; scheduling regression tests where name() was removed.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/0f71752168031b62.json. Report an issue: GitHub.