octobercms/october · error · ApplicationException

backend::lang.media.move_dest_src_match

Error message

backend::lang.media.move_dest_src_match

What it means

Thrown by onMoveItems when the validated destination equals the raw originalPath POST value, i.e. the items would be moved into the folder they are already in. dest goes through MediaLibrary::validatePath() first, so '/' normalizes and still matches originalPath='/' — the widget refuses no-op moves.

Source

Thrown at modules/media/widgets/MediaManager.php:602

    /**
     * onMoveItems AJAX handler
     * @return array
     */
    public function onMoveItems()
    {
        if (!$this->checkHasPermission('mediaDelete')) {
            throw new ForbiddenException;
        }

        $dest = trim(Input::get('dest'));
        if (!strlen($dest)) {
            throw new ApplicationException(Lang::get('backend::lang.media.please_select_move_dest'));
        }

        $dest = MediaLibrary::validatePath($dest);
        if ($dest === Input::get('originalPath')) {
            throw new ApplicationException(Lang::get('backend::lang.media.move_dest_src_match'));
        }

        $files = Input::get('files', []);
        if (!is_array($files)) {
            throw new ApplicationException('Invalid input data');
        }

        $folders = Input::get('folders', []);
        if (!is_array($folders)) {
            throw new ApplicationException('Invalid input data');
        }

        $library = MediaLibrary::instance();

        foreach ($files as $path) {
            /*
             * Move a single file
             */

View on GitHub (pinned to b608633a7e)

Solutions

  1. Select a different destination folder in the popup before confirming
  2. In scripts, assert dest !== originalPath before issuing the request
  3. Treat the error as benign in automation: catch it and skip the move instead of retrying

Example fix

// before
$.request('onMoveItems', { data: { dest, originalPath, files, folders } });

// after
if (dest.trim() !== originalPath) {
    $.request('onMoveItems', { data: { dest, originalPath, files, folders } });
}
Defensive patterns

Strategy: validation

Validate before calling

if (dest.trim() === originalPath) { showToast('Source and destination are the same'); return; }
$.request('onMoveItems', { data: { dest, originalPath, files, folders } });

Type guard

function isNoOpMove(dest, originalPath) {
  return dest.trim() === originalPath;
}

Try / catch

catch (e) { if (/same/i.test(e.message)) { markSkipped(item); continue; } throw e; } // in batch loops

Prevention

When it happens

Trigger: AJAX 'onMoveItems' where dest='/photos' and originalPath='/photos' (moving items into their current folder), including both being the root '/'. Only the exact string match triggers it; moving into a subfolder of the source does not (and is not blocked here).

Common situations: The move dialog preselects the current folder and the user submits without changing it; scripted bulk moves that pass the source path as destination by mistake; UI bug where the selected node in the tree is the active folder.

Related errors


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/3f99b6dcc72208c9. Report an issue: GitHub.