Laravel 13.30 was released on September 2, 2026, covering new collection methods, a storage path hardening change, queue worker diagnostics, and several smaller fixes.
$products->chunkBy('parent');
collect([1, 1, 2, 2, 1, 1])->chunkBy(fn ($value) => $value);
// [[1, 1], [2, 2], [1, 1]]chunkBy() is the most common chunkWhile() pattern turned into a method: it starts a new chunk whenever a key or callback's resolved value changes. Because the key resolves through data_get(), chunkBy('address.city') and similar dot-notation keys work, and each resulting chunk keeps its original array keys intact. Contributed by @JosephSilber in PR #61357.
Storage::path() no longer skips path normalization. Every other filesystem call goes through the Flysystem driver, which throws PathTraversalDetected when a path resolves outside the disk root, but path() previously handed the raw string to Flysystem's PathPrefixer. On the default local disk, path('../../../.env') returned a native path pointing at the application's .env while get() and delete() refused the same argument. path() now runs through WhitespacePathNormalizer before prefixing, and code that relied on .. segments will now throw.
queue:work now writes the worker's stop reason as its final line, for example "Worker STOPPED Memory limit exceeded", and emits a structured record under --json with level, status, reason, exit_code, jobs_processed, memory, and timestamp. The WorkerStopReason enum gained a description() method covering nine exit scenarios, from interrupted to job timed out. Nothing is written under --quiet or --silent.
DevCommands gains two opt-in filters: withoutVendorCommands() drops commands registered from vendor/, and withoutDefaultCommands() drops the framework defaults (serve, queue:listen, pail, Vite). Both leave application-registered commands alone, filtering on the same origin value DevCommands already tracked for name collisions.
Native sqlsrv: DSN connection strings for Microsoft SQL Server are now detected before URL parsing and handled by a dedicated parser that extracts host, port, database, and PDO_SQLSRV options such as Encrypt, TrustServerCertificate, MultiSubnetFailover, ApplicationIntent, and LoginTimeout. Previously parse_url() treated the whole DSN as a path and mangled the configuration. The sqlsrv://user:pass@host:port/database URL convention keeps working.
Artisan::commandNamed('app:my-command') returns a single command instance or null without constructing every registered command, unlike Artisan::all(). The Laravel Cloud queue implements totalPendingSize(), totalDelayedSize(), and totalReservedSize() by summing across managedQueues(), where SQS returns 0 because it cannot enumerate queues.
Fixes include route:cache restoring the facade application after bootstrapping its throwaway copy (previously facades pointed at a discarded container, causing LogicException under php artisan optimize), Request::clamp() falling back to the default for non-numeric input instead of a 500, db:seed restoring the default connection via try/finally, setVisibility() resolving through readerFor() on read-through disks, Queue::createPayloadUsing() no longer requiring a resolved connection, exception page tooltips rendering with allowHTML: false by default, JSON:API nested include paths resolving against the right level, spl_object_id() replacing spl_object_hash() in the container and Eloquent builder, and a quadratic wildcard rule expansion fix backported to 12.x.




Comments
No comments yet — be the first.
Open the discussion
No account or password needed — just enter your e-mail and we’ll send you a one-time sign-in link. First time here? You’re set up automatically.
Your rating will be applied automatically after you sign in.
Check your inbox
We’ve sent a sign-in link to …. Open it on this device — this tab will sign you in automatically.
Nothing arrived? Check your spam folder — and mark the mail as "Not spam" so it lands in your inbox next time.