{"record":{"id":"50c56c3faf0d3037","repo":"octobercms/october","slug":"editor-lang-filesystem-error-renaming","errorCode":null,"errorMessage":"editor::lang.filesystem.error_renaming","messagePattern":"editor::lang\\.filesystem\\.error_renaming","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"modules/editor/traits/FileSystemFunctions.php","lineNumber":109,"sourceCode":"        if (\n            !is_dir($originalFullPath) &&\n            Config::get('media.clean_vectors', true) &&\n            strtolower(File::extension($newName)) === 'svg' &&\n            strtolower(File::extension($originalPath)) !== 'svg'\n        ) {\n            throw new ApplicationException(Lang::get(\n                'editor::lang.filesystem.type_not_allowed',\n                ['allowed_types' => implode(', ', array_diff($allowedFileExtensions, ['svg']))]\n            ));\n        }\n\n        $newFullPath = $basePath.'/'.dirname($originalPath).'/'.$newName;\n        if (file_exists($newFullPath) && $newFullPath !== $originalFullPath) {\n            throw new ApplicationException(Lang::get('editor::lang.filesystem.already_exists'));\n        }\n\n        if (!@rename($originalFullPath, $newFullPath)) {\n            throw new ApplicationException(Lang::get('editor::lang.filesystem.error_renaming'));\n        }\n    }\n\n    /**\n     * editorDeleteFileOrDirectory\n     */\n    protected function editorDeleteFileOrDirectory($basePath, $fileList)\n    {\n        // Delete leaves first\n        usort($fileList, function($a, $b) {\n            return strlen($b) - strlen($a);\n        });\n\n        foreach ($fileList as $path) {\n            if (!$this->validateFileSystemPath($path)) {\n                throw new ApplicationException(Lang::get('editor::lang.filesystem.invalid_path'));\n            }\n","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/editor/traits/FileSystemFunctions.php#L91-L127","documentation":"Thrown by editorRenameFileOrDirectory when the native PHP rename() call (error-suppressed with @) returns false (line 108-109). All validation passed, so this is an OS-level failure: the PHP/webserver user lacks write permission on the file or its directory, the file is locked (Windows), the target is on a different filesystem/mount, or SELinux denies the operation.","triggerScenarios":"command_onAssetRename that survives every validation but @rename() fails: themes/<theme>/assets not writable by the webserver user; asset files created by root/CLI so the webserver user cannot modify the directory entry; open file handles on Windows; assets mounted read-only (NFS mount, container volume ro).","commonSituations":"Deployments that write assets as root while PHP runs as www-data; local dev where files were created by a different user than the one running php-fpm; SELinux/AppArmor policies on RHEL-based hosts; synced/mounted theme directories flagged read-only.","solutions":["Give the PHP user write access to the directory and the file: chown -R www-data:www-data themes/<theme>/assets && chmod -R u+rwX (renaming requires write on the DIRECTORY entry)","Check for open handles (lsof <file>) on Windows/locked-file cases and close the program holding it","Verify the mount is read-write (mount | grep themes) and SELinux context is httpd_sys_rw_content_t","If the target crosses filesystems, confirm both source and destination mounts allow the operation for the PHP user"],"exampleFix":"# before: root-owned assets block rename\n$ ls -la themes/demo/assets | head\n# after\n$ sudo chown -R www-data:www-data themes/demo/assets\n$ sudo chmod -R u+rwX themes/demo/assets","handlingStrategy":"try-catch","validationCode":"$orig = $assetsBase.'/'.$originalPath;\n$target = $assetsBase.'/'.dirname($originalPath).'/'.$newName;\nif (!is_writable($orig) || !is_writable(dirname($target))) {\n    // fix ownership/permissions before attempting the rename\n}","typeGuard":null,"tryCatchPattern":"use October\\Rain\\Exception\\ApplicationException;\n\ntry {\n    rename($originalFullPath, $newFullPath);\n} catch (Throwable $e) {\n    // fall back to copy + unlink when rename fails across devices/locks\n    if (!@copy($originalFullPath, $newFullPath) || !@unlink($originalFullPath)) {\n        throw new ApplicationException(Lang::get('editor::lang.filesystem.error_renaming'));\n    }\n}","preventionTips":["Keep themes/<theme>/assets owned by the webserver user in every environment","Avoid creating assets as root/CLI that the webserver must later rename","Close programs holding asset files open before renaming on Windows"],"tags":["filesystem","permissions","io","editor","winter-cms"],"backgroundTag":"filesystem-permission-denied","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}