<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/collections-chunkby-and-storage-path-hardening-in-laravel-13-30-oydrci59q" -->

---
title: Collections chunkBy() and Storage Path Hardening in...
description: Laravel 13.30 adds a chunkBy() collection method that starts a new chunk whenever a resolved key or callback value changes, replacing the common chunkWhile()...
canonical: https://daily.dev/posts/collections-chunkby-and-storage-path-hardening-in-laravel-13-30-oydrci59q
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Collections chunkBy() and Storage Path Hardening in Laravel 13.30 | daily.dev
og:description: Laravel 13.30 adds a chunkBy() collection method that starts a new chunk whenever a resolved key or callback value changes, replacing the common chunkWhile()...
og:url: https://daily.dev/posts/collections-chunkby-and-storage-path-hardening-in-laravel-13-30-oydrci59q
og:image: https://api.daily.dev/og/posts/OydrCI59q.png
og:image:alt: Collections chunkBy() and Storage Path Hardening in Laravel 13.30
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Collections chunkBy() and Storage Path Hardening in Laravel 13.30

**[Laravel News](https://daily.dev/sources/ln)** · 8 min read · 0 upvotes · 0 comments

## Summary

Laravel 13.30 adds a chunkBy() collection method that starts a new chunk whenever a resolved key or callback value changes, replacing the common chunkWhile() comparison pattern. Storage::path() now runs through the same WhitespacePathNormalizer used by every other Flysystem call, so paths escaping the disk root throw PathTraversalDetected instead of returning a string pointing outside the disk (code relying on '..' segments will now throw). queue:work prints the worker's stop reason as its final output line and as a structured field with --json, covering nine exit scenarios. Other additions include DevCommands::withoutVendorCommands()/withoutDefaultCommands(), native sqlsrv: DSN parsing for SQL Server, Artisan::commandNamed() for resolving a single command lazily, and Cloud queue total size methods. The release also fixes a route:cache bug that left facades pointed at a discarded application, a 500 error from Request::clamp() on non-numeric input, and several other queue, seeding, and validation issues.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://laravel-news.com/laravel-13-30-0>

## Questions this post answers

### Why does Storage::path() in Laravel now throw an exception for paths with '..' segments?

Laravel 13.30 changed Storage::path() to run arguments through the same WhitespacePathNormalizer that every other Flysystem filesystem call uses, so paths resolving outside the disk root now throw PathTraversalDetected instead of returning a string. Previously path() skipped normalization and could return a native path pointing outside the disk, unlike get(), delete(), and readStream(), which already rejected such input. Code relying on the old behavior with '..' segments will now throw.

_Track breaking changes like this Laravel Storage::path() fix before they surface in production on daily.dev._

### What does chunkBy() do differently from chunkWhile() in Laravel collections?

chunkBy(), added in Laravel 13.30, starts a new chunk whenever a resolved key or callback value changes, capturing the most common comparison pattern people already wrote manually with chunkWhile(). It accepts a key string (resolved via data_get(), so dot notation like 'address.city' works) or a callback, and preserves original keys inside each chunk, for example collect([1,1,2,2,1,1])->chunkBy(fn($v)=>$v) returns [[1,1],[2,2],[1,1]].

_Developers comparing collection helpers across Laravel versions can follow additions like chunkBy() on daily.dev._

### How do I see why a Laravel queue worker stopped running?

Starting in Laravel 13.30, queue:work writes the worker's stop reason as its final console line, for example 'Worker STOPPED Memory limit exceeded', and outputs it as a structured JSON field when using --json. The WorkerStopReason enum gained a description() method covering nine exit scenarios including memory limit exceeded, maximum run time exceeded, and job timed out; nothing prints under --quiet or --silent.

_Anyone debugging queue worker crashes can keep up with Laravel queue tooling changes on daily.dev._

## Similar posts on daily.dev

- [Storage Cache Store in Laravel 13.10.0](https://daily.dev/posts/storage-cache-store-in-laravel-13-10-0-r1lc1xf37) · Laravel News · 35 upvotes · 5 comments

---

Tags: [#php](https://daily.dev/tags/php), [#laravel](https://daily.dev/tags/laravel)

[View this post on daily.dev](https://daily.dev/posts/collections-chunkby-and-storage-path-hardening-in-laravel-13-30-oydrci59q)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Collections chunkBy() and Storage Path Hardening in Laravel 13.30","url":"https://daily.dev/posts/collections-chunkby-and-storage-path-hardening-in-laravel-13-30-oydrci59q","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/collections-chunkby-and-storage-path-hardening-in-laravel-13-30-oydrci59q"},"datePublished":"2026-09-02T13:27:58.691Z","dateModified":"2026-09-02T13:37:05.212Z","description":"Laravel 13.30 adds a chunkBy() collection method that starts a new chunk whenever a resolved key or callback value changes, replacing the common chunkWhile()...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ee40e2048594e45913dd31bd66f36e1c?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ee40e2048594e45913dd31bd66f36e1c?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Laravel News","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Laravel News","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/ln","url":"https://daily.dev/sources/ln"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/collections-chunkby-and-storage-path-hardening-in-laravel-13-30-oydrci59q","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"php,laravel","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Laravel News","item":"https://daily.dev/sources/ln"},{"@type":"ListItem","position":3,"name":"Collections chunkBy() and Storage Path Hardening in Laravel 13.30"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/collections-chunkby-and-storage-path-hardening-in-laravel-13-30-oydrci59q#faq","mainEntity":[{"@type":"Question","name":"Why does Storage::path() in Laravel now throw an exception for paths with '..' segments?","acceptedAnswer":{"@type":"Answer","text":"Laravel 13.30 changed Storage::path() to run arguments through the same WhitespacePathNormalizer that every other Flysystem filesystem call uses, so paths resolving outside the disk root now throw PathTraversalDetected instead of returning a string. Previously path() skipped normalization and could return a native path pointing outside the disk, unlike get(), delete(), and readStream(), which already rejected such input. Code relying on the old behavior with '..' segments will now throw. Track breaking changes like this Laravel Storage::path() fix before they surface in production on daily.dev."}},{"@type":"Question","name":"What does chunkBy() do differently from chunkWhile() in Laravel collections?","acceptedAnswer":{"@type":"Answer","text":"chunkBy(), added in Laravel 13.30, starts a new chunk whenever a resolved key or callback value changes, capturing the most common comparison pattern people already wrote manually with chunkWhile(). It accepts a key string (resolved via data_get(), so dot notation like 'address.city' works) or a callback, and preserves original keys inside each chunk, for example collect([1,1,2,2,1,1])->chunkBy(fn($v)=>$v) returns [[1,1],[2,2],[1,1]]. Developers comparing collection helpers across Laravel versions can follow additions like chunkBy() on daily.dev."}},{"@type":"Question","name":"How do I see why a Laravel queue worker stopped running?","acceptedAnswer":{"@type":"Answer","text":"Starting in Laravel 13.30, queue:work writes the worker's stop reason as its final console line, for example 'Worker STOPPED Memory limit exceeded', and outputs it as a structured JSON field when using --json. The WorkerStopReason enum gained a description() method covering nine exit scenarios including memory limit exceeded, maximum run time exceeded, and job timed out; nothing prints under --quiet or --silent. Anyone debugging queue worker crashes can keep up with Laravel queue tooling changes on daily.dev."}}]}
```

