{"record":{"id":"bdd41637b27643bb","repo":"laravel/framework","slug":"to-enable-support-for-closure-jobs-please-install","errorCode":null,"errorMessage":"To enable support for closure jobs, please install the illuminate/queue package.","messagePattern":"To enable support for closure jobs, please install the illuminate/queue package\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Bus/Queueable.php","lineNumber":321,"sourceCode":"            $this->chained = array_merge($this->chained, [$this->serializeJob($job)]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Serialize a job for queuing.\n     *\n     * @param  mixed  $job\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function serializeJob($job)\n    {\n        if ($job instanceof Closure) {\n            if (! class_exists(CallQueuedClosure::class)) {\n                throw new RuntimeException(\n                    'To enable support for closure jobs, please install the illuminate/queue package.'\n                );\n            }\n\n            $job = CallQueuedClosure::create($job);\n        }\n\n        return serialize($job);\n    }\n\n    /**\n     * Dispatch the next job on the chain.\n     *\n     * @return void\n     */\n    public function dispatchNextJobInChain()\n    {\n        if (is_array($this->chained) && ! empty($this->chained)) {","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Bus/Queueable.php#L303-L339","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before (closure job, illuminate/queue missing)\ndispatch(function () use ($order) {\n    Mail::to($order->user)->send(new OrderConfirmation($order));\n});\n\n// after\n// composer require illuminate/queue\n// OR convert to a named job:\nclass SendOrderConfirmation implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;\n    public function __construct(public Order $order) {}\n    public function handle(): void\n    {\n        Mail::to($this->order->user)->send(new OrderConfirmation($this->order));\n    }\n}\ndispatch(new SendOrderConfirmation($order));","handlingStrategy":"validation","validationCode":"// Validate closure-job support before dispatching closures\nif (! class_exists(\\Illuminate\\Queue\\CallQueuedClosure::class)) {\n    throw new \\RuntimeException('illuminate/queue is required to dispatch closure jobs.');\n}\ndispatch(fn () => Mail::to($user)->send(new WelcomeMail));","typeGuard":"function closureJobsAreSupported(): bool\n{\n    return class_exists(\\Illuminate\\Queue\\CallQueuedClosure::class);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["bus","queue","closures","dependencies"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}