laravel/framework · error · RuntimeException
To enable support for closure jobs, please install the illum
Error message
To enable support for closure jobs, please install the illuminate/queue package.
What it means
Thrown by Schedule::dispatchToQueue() (src/Illuminate/Console/Scheduling/Schedule.php:250) when a scheduled closure-based job is dispatched to the queue but CallQueuedClosure (from illuminate/queue) is not present. Closures must be serialized into a CallQueuedClosure object for queue transport.
Source
Thrown at src/Illuminate/Console/Scheduling/Schedule.php:250
return $event;
}
/**
* Dispatch the given job to the queue.
*
* @param object $job
* @param string|null $queue
* @param string|null $connection
* @return void
*
* @throws \RuntimeException
*/
protected function dispatchToQueue($job, $queue, $connection)
{
if ($job instanceof Closure) {
if (! class_exists(CallQueuedClosure::class)) {
throw new RuntimeException(
'To enable support for closure jobs, please install the illuminate/queue package.'
);
}
$job = CallQueuedClosure::create($job);
}
if ($job instanceof ShouldBeUnique) {
return $this->dispatchUniqueJobToQueue($job, $queue, $connection);
}
$this->getDispatcher()->dispatch(
$job->onConnection($connection)->onQueue($queue)
);
}
/**
* Dispatch the given unique job to the queue.View on GitHub (pinned to bd6b5437e6)
Solutions
- composer require illuminate/queue.
- If you don't need queueing, don't queue the closure — run it inline (remove onQueue).
- Convert the closure into a real job class implementing ShouldQueue; real classes don't require CallQueuedClosure.
- Re-run composer dump-autoload after installing.
Example fix
// before
$schedule->call(fn () => process())->everyMinute()->onQueue('default');
// illuminate/queue not installed
// after
// composer require illuminate/queue
$schedule->call(fn () => process())->everyMinute()->onQueue('default');
// or convert to a real job:
$schedule->job(ProcessJob::class)->everyMinute()->onQueue('default'); Defensive patterns
Strategy: validation
Validate before calling
if (! class_exists(\Illuminate\Queue\CallQueuedClosure::class)) {
// don't queue closures; convert to a job class or install illuminate/queue
} Type guard
function canQueueClosures(): bool
{
return class_exists(\Illuminate\Queue\CallQueuedClosure::class);
} Try / catch
try {
$schedule->call(fn () => work())->onQueue('default');
} catch (\RuntimeException $e) {
$schedule->call(fn () => work()); // run inline
} Prevention
- Install illuminate/queue when queueing closures.
- Convert closures to real ShouldQueue job classes for portability.
- Document the illuminate/queue dependency for queue-backed schedules.
When it happens
Trigger: Schedule::call(fn () => ...)->onQueue(...) or Schedule::job(SomeJob) where the dispatched job ends up being a Closure, in a project where illuminate/queue is not installed (illuminate/bus-only or standalone illuminate/console setup).
Common situations: Standalone illuminate/console + illuminate/bus without illuminate/queue; partial Laravel subset for a CLI tool that tries to queue closures.
Related errors
- Unable to resolve the dispatcher from the service container.
- A container implementation is required to use the scheduler.
- Cache driver not available. Scheduling unique jobs not suppo
- Ably error: %s
- Please install the "spatie/fork" Composer package in order t
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/3245c3e9a97bea63.json.
Report an issue: GitHub.