Skip to content

file.changeName() leaves UUID stub at old path; Panel creates _changes draft under wrong filename for orphaned sidecars #8104

Description

@DustinStupp

Environment

  • Kirby: 5.3.2
  • PHP: 8.2
  • Multilingual: yes (EN default, DE, ZH)
  • OS: macOS 15

What happened

Using a file.create:after hook that calls $file->changeName($newBase) to auto-rename uploaded files.
Two related bugs appear:


Bug 1 — changeName() leaves a UUID-only stub at the old filename

After calling changeName(), the renamed file and its sidecar are created correctly at the new path. However, a UUID-only stub (22 bytes, Uuid: <originalUUID>) is left behind at the original sidecar path, with no corresponding media file.

Steps to reproduce:

  1. Upload photo.jpg to a page in a multilingual site
  2. In a file.create:after hook, call $file->changeName('newname')
  3. Inspect the page's content folder

Expected:

  • newname.jpg
  • newname.jpg.en.txt ✓ (with full content)
  • photo.jpg.en.txt — deleted

Actual:

  • newname.jpg
  • newname.jpg.en.txt ✓ (with full content, new UUID)
  • photo.jpg.en.txt still exists — contains only Uuid: <originalUUID> (22 bytes)

Since photo.jpg no longer exists, Kirby's file collection for the page encounters a sidecar with no corresponding media file, causing errors when rendering the page.


Bug 2 — Orphaned sidecar misidentified as page content; Panel creates wrong _changes draft

When photo.jpg.en.txt (the stub from Bug 1) survives after the rename, and the user later opens the page in the Panel, Kirby's content scanner cannot find a corresponding photo.jpg media file. It therefore misidentifies the orphaned sidecar as the page content file.

The Panel then:

  1. Creates _changes/photo.jpg.en.txt as a draft — containing the actual page content (Title, UUID matching the page, Page-layout blocks, etc.) rather than file metadata
  2. This draft persists across uploads and can be published, recreating the orphan in the main content folder with the page's UUID embedded

This means any subsequent cleanup of photo.jpg.en.txt from the main folder may be undone when the Panel publishes the stale _changes draft.


Notes

  • Calling update() on $file before changeName() returns a new File object (immutable model) — the changeName() call must use this updated object or Kirby throws "Storage for the file is immutable and cannot be moved."
  • The UUID stub left by changeName() has the original UUID (pjsl3eeauhp4j5it), while the new sidecar gets a new UUID (1mdypinsdsbkv5iy). Content saved before the rename that references the old UUID via file://pjsl3eeauhp4j5it will therefore be broken regardless of the stub cleanup.
  • rename() (deprecated) may have had the same behaviour; confirmed on changeName() in 5.3.2.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions