Laravel 13.34.0 se publicó el 30 de septiembre de 2026. Esta versión cambia el tratamiento de los fallos en las colas y reúne varias correcciones para el ORM, las herramientas de esquema, las pruebas, la caché y las integraciones de plataforma.

ProcessPodcast.php
use Illuminate\Queue\Attributes\CountCrashesAsExceptions;
use Illuminate\Queue\Attributes\MaxExceptions;

#[MaxExceptions(3), CountCrashesAsExceptions]
class ProcessPodcast implements ShouldQueue
{
    public function retryUntil(): DateTime
    {
        return now()->addHour();
    }
}

William Julian-Vicary incorporó el atributo opcional CountCrashesAsExceptions para los jobs en cola. Una excepción lanzada ya se contabilizaba en el valor de $maxExceptions. Un worker terminado por falta de memoria, un fallo de segmentación o la detención de un contenedor no se contaba como excepción. Por ese motivo, un job que usara retryUntil() con un rate limiter podía seguir provocando cierres de workers hasta que venciera su plazo.

Con el nuevo atributo, un intento terminado por un crash suma una excepción. La propiedad pública $countCrashesAsExceptions = true ofrece el mismo resultado. El worker escribe una clave de caché cuando inicia un job configurado con esta opción y la elimina cuando el intento termina. Si la clave sigue presente en el siguiente intento, Laravel interpreta que la ejecución anterior acabó por un fallo del worker. El job debe definir maxExceptions. Cada intento añade dos operaciones de caché, por lo que la función es optativa. El cambio está en la pull request #61737.

Jack Bayliss modificó el tratamiento de los timeouts para los jobs que implementan Illuminate\Contracts\Queue\Interruptible. Cuando se alcanza el límite, el worker envía ahora SIGALRM. La función interrupted() puede guardar así el progreso antes de que el job falle. Las versiones anteriores enviaban señales como SIGTERM para otras interrupciones. Un timeout podía terminar el worker sin avisar al job.

El worker también emite JobInterrupted, un evento añadido en Laravel 13.31. Las excepciones lanzadas por interrupted() se registran mientras el timeout sigue su curso. La modificación corresponde a la pull request #61651.

El evento JobProcessed incorpora una propiedad duration expresada en milisegundos. Cuando el evento procede de un worker, el valor es un float redondeado a dos decimales. Si se emite desde otro lugar, su valor es null. Las aplicaciones pueden medir la duración sin enlazar siempre los eventos JobProcessing y JobProcessed. Esta función llegó con la pull request #61672.

queue:flush acepta ahora --queue. Los operadores pueden borrar los jobs fallidos de una cola concreta y conservar los de las demás. La opción se puede combinar con --hours, por ejemplo queue:flush --queue=sftp-sync --hours=48, para mantener los fallos recientes. La mejora está registrada en la pull request #61630.

Schema::getColumn('users', 'email') devuelve los metadatos de una sola columna. El resultado incluye campos como type_name y nullable. Si la columna no existe, la función devuelve un array vacío. Pull request #61759 añadió este método.

assertDatabaseCount() acepta un array de pares formados por tabla y cantidad. Una prueba puede comprobar varios modelos Eloquent o nombres de tablas con una sola aserción. El cambio está descrito en la pull request #61727.

App::environment() y el método environments() del scheduler aceptan enums. La directiva Blade @env también los admite porque se compila mediante App::environment(). Queue::isPaused() acepta enums y queda alineado con Queue::pause() y Queue::resume(). Antes, pasar un enum a App::environment() provocaba un error. En environments(), podía impedir la ejecución de una tarea programada. Estas modificaciones corresponden a las pull requests #61730 y #61725.

Relation::requireMorphMap() controla ahora también la lectura de las relaciones polimórficas. Laravel ya rechazaba el guardado de un modelo sin entrada en la morph map. El lazy loading y el eager loading lanzan ahora ClassMorphViolationException cuando un valor *_type no aparece en la map. Las aplicaciones que no activan requireMorphMap() mantienen el comportamiento anterior. Pull request #61711 añadió esta comprobación.

El resto de Laravel 13.34.0 reúne correcciones y ajustes de compatibilidad. Los valores de LazyCollection funcionan en las cláusulas between (#61678), y LazyCollection::combine() lanza ValueError cuando las longitudes no coinciden (#61696). Los atributos actualizados se sincronizan con el estado original después de increment o decrement. También se excluyen al replicar modelos (#61680, #61751). Number::parseInt() procesa valores superiores al rango de 32 bits. Number::format(), percentage() y currency() ya no devuelven -0 (#61691, #61716). Collection::mode() trata correctamente los valores nulos (#61686), shift($count) devuelve una colección vacía cuando la colección de origen está vacía (#61723), y trans_choice() selecciona la forma plural correcta para números negativos (#61700).

PhpRedisLock::refresh() funciona con la serialización de phpredis activada (#61690). DatabaseLock ya no oculta deadlocks dentro de una transacción (#61708). sortBy() conserva los valores fraccionarios cuando se usan varias columnas y SORT_NUMERIC (#61699). Los reintentos de solicitudes multipart conservan el contenido de los streams adjuntos (#61728). Eloquent whereNot() ya no aplica una doble negación a condiciones en arrays (#61721). Las consultas de relaciones respetan la clave propietaria en whereMorphedTo() y whereNotMorphedTo() (#61712). wherePivotBetween() funciona con sync(), detach() y updateExistingPivot() (#61747). through() ya no devuelve HasOneThrough para relaciones MorphMany (#61760), y findOrFail() admite arrays de IDs enum (#61765).

La salida de queue:restart informa ahora cuando un worker no puede reiniciarse (#61706). Laravel añade Cloud exceptions (#61704), proveedores de credenciales S3 con nombre y discos Cloud IAM (#61676), además de soporte para phpstan/phpstan:2.2.15 (#61719). Con Cloud Postgres en modo pool se conservan las opciones PDO existentes cuando se fuerzan las prepared statements emuladas (#61735). Los locks de Memcached superiores a 30 días ya no caducan de inmediato (#61742). Redis throttling deja de devolver una marca de tiempo como número de intentos restantes (#61748). También se incorporó una prueba de regresión para createPayloadUsing en el gestor de colas (#61773).

La directiva Blade elsePushIf procesa correctamente las condiciones complejas (#61741). ArrayStore::touch() interpreta literalmente las claves con puntos (#61777). memoized tagged-cache many() ya no devuelve null para claves numéricas (#61780). Los detalles de los archivos reportables incluyen el tipo MIME (#61772). Las exclusiones del validador usan búsquedas de tiempo constante (#61698). La versión incluye correcciones de Markdown (#61746), una limpieza final de Mockery (#61739), mejoras de documentación y pruebas (#61679, #61683, #61697, #61663), además de ajustes de StyleCI (#61763).

Los workflows de CI se ejecutan ahora en Windows 2025. Se corrigió una prueba inestable del scheduler en Windows (#61718, #61768). Imagick se habilita de forma explícita para las pruebas de CI (#61756).