Skip to content

stache:refresh flattens a collection tree #14996

Description

@aerni

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions