laravel/framework · error · RuntimeException
To enable support for closure jobs, please install the…
Error message
To enable support for closure jobs, please install the illuminate/queue package.
What it means
Queueable::serializeJob is invoked when a Queueable object chains or pushes a closure as part of its job payload. Closures cannot be serialized to PHP strings directly; Laravel requires the illuminate/queue package which provides CallQueuedClosure, a wrapper that serializes the closure via Opis/Closure. Without illuminate/queue installed, no closure-based job can be queued.
Solutions
- Require illuminate/queue in composer.json (composer require illuminate/queue) matching the installed illuminate/bus version.
- Avoid dispatching closures; convert the closure to a named job class implementing ShouldQueue, which needs no CallQueuedClosure.
- If you intentionally exclude illuminate/queue, ensure no code path calls Queueable::serializeJob with a Closure (audit ->chain() and dispatch() callers).
Example fix
// before (closure job, illuminate/queue missing)
dispatch(function () use ($order) {
Mail::to($order->user)->send(new OrderConfirmation($order));
});
// after
// composer require illuminate/queue
// OR convert to a named job:
class SendOrderConfirmation implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(public Order $order) {}
public function handle(): void
{
Mail::to($this->order->user)->send(new OrderConfirmation($this->order));
}
}
dispatch(new SendOrderConfirmation($order)); Defensive patterns
Strategy: validation
Validate before calling
// Validate closure-job support before dispatching closures
if (! class_exists(\Illuminate\Queue\CallQueuedClosure::class)) {
throw new \RuntimeException('illuminate/queue is required to dispatch closure jobs.');
}
dispatch(fn () => Mail::to($user)->send(new WelcomeMail)); Type guard
function closureJobsAreSupported(): bool
{
return class_exists(\Illuminate\Queue\CallQueuedClosure::class);
} Prevention
- In standalone illuminate/bus projects, declare illuminate/queue as a dependency upfront.
- Prefer named job classes over closure dispatch in any project where dependencies may vary.
- Lock composer.json: avoid 'replace'/'exclude' on illuminate/queue in custom distributions.
- Add a smoke test that dispatches a closure job in CI to catch missing package early.
When it happens
Trigger: Calling dispatch(function () { ... }) (closure dispatch) or chaining ->chain([fn () => ...]) from a Queueable job while illuminate/queue is not installed. Most common when consuming illuminate/bus or illuminate/database standalone without the full framework.
Common situations: Using illuminate/bus as a standalone dependency in a non-Laravel project. Splitting a Laravel monolith into a micro-service that pulls only part of illuminate/* and forgets illuminate/queue. Composer replace/exclude on illuminate/queue in a custom distribution.
Related errors
- Attempted to batch job
- Queue resolver did not return a Queue implementation.
- Please install the "spatie/fork" Composer package in order…
- Queueable entity [ ] not found for ID [ ].
- Queueing collections with multiple model connections is not…
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/bdd41637b27643bb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Bus/Queueable.php:321
$this->chained = array_merge($this->chained, [$this->serializeJob($job)]);
}
return $this;
}
/**
* Serialize a job for queuing.
*
* @param mixed $job
* @return string
*
* @throws \RuntimeException
*/
protected function serializeJob($job)
{
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);
}
return serialize($job);
}
/**
* Dispatch the next job on the chain.
*
* @return void
*/
public function dispatchNextJobInChain()
{
if (is_array($this->chained) && ! empty($this->chained)) {View on GitHub (pinned to e0f6eb3518)