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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions