[5.x]: Moving an asset with “Replace it” throws TypeError: volumeUid must be of type string, null given

Open Beginner friendly
#20,128 2 comments 0 reactions 1 assignee View on GitHub

Maintainers usually reply within 1 day

@i-just is already working on this.

Since Oct 28, 2026.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
php
Domain
backend

Research direction

Start in AssetsController::actionMoveAsset() in the control panel assets controller, at the branch where force is set and the conflicting asset is queried with ->select(['elements.id']). Trace the following requireVolumePermissionByAsset() call into requireVolumePermission() to confirm the volume UID is null, then widen the select to include assets.volumeId and assets.uploaderId. Done looks like: moving an asset into a volume that already has that filename, choosing "Replace it", actually moves the file, returns the success toast, and no longer throws the volumeUid must be of type string, null given TypeError; reproduce with two volumes holding the same filename.

Written by the indexing model from the issue text.

Description

bug repo:cms
What happened?
Description

When moving a file from one volume to another in Assets, if a file with the same filename exists in the other volume and you select the "replace it" option the file does not get moved but the toast says it has moved.

(Claude Code's bugfind and fix)

In AssetsController::actionMoveAsset(), when force is set, the conflicting asset is queried with ->select(['elements.id']), so volumeId is never loaded. The following requireVolumePermissionByAsset('deleteAssets', $conflictingAsset) then calls requireVolumePermission() with a null volume UID and throws a TypeError. The control panel still reports success, but nothing is moved.

Fix: also select assets.volumeId (and assets.uploaderId for the peer permission checks).

->select(['elements.id']) to ->select(['elements.id', 'assets.volumeId', 'assets.uploaderId'])

Steps to reproduce
  1. move an asset into a folder (here, a different volume) that already has an asset with the same filename, then choose “Replace it”.
Expected behavior

File is moved

Actual behavior

File is not moved and the following error is thrown: TypeError: volumeUid must be of type string, null given

Craft CMS version

5.11.5.1

PHP version

No response

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions
Dominant language
PHP
Stars
3.6k
Forks
712
Avg merge
13h 5m
Merged PRs (30d)
328

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from craftcms/cms

All issues in craftcms/cms

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.