New in Laravel 13.36. A mailable queued with SerializesModels only keeps the identifier of its models; the worker reads them again before sending. If a model was deleted in the meantime, it throws a ModelNotFoundException, and the job fails.
For a job (ShouldQueue), the #[DeleteWhenMissingModels] attribute has handled this case for a long time: the job is removed from the queue, without failing. Queued mailables ignored it.
Since Laravel 13.36
Queued mailables read #[DeleteWhenMissingModels], and also #[FailOnTimeout] (an email that runs past its timeout is marked as failed instead of being retried, which could send it twice):
use Illuminate\Queue\Attributes\DeleteWhenMissingModels; #[DeleteWhenMissingModels] class OrderShipped extends Mailable implements ShouldQueue { use Queueable, SerializesModels; public function __construct(public Order $order) {} }
Your task
When the warehouse ships an order, the "Your order is on its way" email is queued. But a customer sometimes cancels just before the worker gets to it: the order is deleted, and each time a job is added to failed_jobs, where the team finds it the next day.
Make the email of an order that has disappeared simply be dropped.