Bug description
Running php please stache:refresh on a structured collection with structure.root: true flattens the tree in the warmed Stache cache: every entry is moved to the root level and whichever entry sorts first in queryEntries() becomes the site root. In my case a redirect entry became the root, so the homepage (/de) started serving a 301.
Running the two commands separately — please stache:clear then please stache:warm — produces the correct tree every time. The on-disk tree file is never touched; only the warmed cache is affected.
How to reproduce
Create a structured collection with structure.root: true and a nested tree with a real "home" entry as the root.
Warm with separate commands, confirm it's correct:
php please stache:clear
php please stache:warm
Entry::find('home')->uri() → / ✅
Run refresh:
php please stache:refresh
Entry::find('home')->uri() → /home ❌ (tree flattened, first queryEntries() entry is now root).
Re-run clear + warm to recover.
Logs
Environment
Environment
Laravel Version: 13.19.0
PHP Version: 8.5.8
Composer Version: 2.10.1
Environment: local
Debug Mode: ENABLED
Maintenance Mode: OFF
Timezone: Europe/Vienna
Locale: en
Cache
Config: CACHED
Events: CACHED
Routes: CACHED
Views: CACHED
Drivers
Broadcasting: log
Cache: file
Database: sqlite
Logs: stack / single, flare
Mail: log
Queue: redis
Session: file
Storage
public/assets: LINKED
Locales
Installed: de, en, fr
LaravelLang\Actions\Plugin: 1.13.2
LaravelLang\Attributes\Plugin: 2.16.4
LaravelLang\HttpStatuses\Plugin: 3.13.2
LaravelLang\Lang\Plugin: 15.32.0
LaravelLang\MoonShine\Plugin: INCORRECT
LaravelLang\StarterKits\Plugin: 1.16.0
Locales Version: 2.11.0
Protected: en
Publisher Version: 16.8.0
Livewire
Livewire: v4.3.3
Statamic
Addons: 9
License Key: Set
Sites: 2 (Deutsch, Englisch)
Stache Watcher: Enabled (auto)
Static Caching: full
Version: 6.24.2 PRO
Statamic Addons
aerni/advanced-seo: 3.2.1
aerni/font-awesome: 4.0.1
aerni/livewire-forms: 10.3.1
aerni/social-links: 4.1.1
aerni/zipper: 2.5.0
jacksleight/statamic-bard-texstyle: 4.1.1
marcorieser/statamic-livewire: 5.3.1
spatie/statamic-responsive-images: 6.2.0
tfd/statamic-aida: 2.2.0
Installation
Fresh statamic/statamic site via CLI
Additional details
Expected behavior
stache:refresh warms the same nested tree as a separate clear + warm, keeping the root: true entry at the root.
Possible cause
During the single-process clear()→warm(), CollectionStructure::validateTree() runs against an empty input tree, so every entry is treated as "missing" and appended flat at the root (array_merge([], $missingEntries)). A fresh warm process reads the tree from disk first and warms it correctly.
Bug description
Running
php please stache:refreshon a structured collection withstructure.root: trueflattens the tree in the warmed Stache cache: every entry is moved to the root level and whichever entry sorts first inqueryEntries()becomes the site root. In my case a redirect entry became the root, so the homepage (/de) started serving a301.Running the two commands separately — please stache:clear then please stache:warm — produces the correct tree every time. The on-disk tree file is never touched; only the warmed cache is affected.
How to reproduce
Create a structured collection with
structure.root: trueand a nested tree with a real "home" entry as the root.Warm with separate commands, confirm it's correct:
Entry::find('home')->uri()→/✅Run refresh:
Entry::find('home')->uri()→/home❌ (tree flattened, firstqueryEntries()entry is now root).Re-run clear + warm to recover.
Logs
Environment
Installation
Fresh statamic/statamic site via CLI
Additional details
Expected behavior
stache:refreshwarms the same nested tree as a separateclear+warm, keeping theroot: trueentry at the root.Possible cause
During the single-process
clear()→warm(),CollectionStructure::validateTree()runs against an empty input tree, so every entry is treated as "missing" and appended flat at the root (array_merge([], $missingEntries)). A freshwarmprocess reads the tree from disk first and warms it correctly.