{"record":{"id":"49cbeee2580149fb","repo":"yiisoft/yii2","slug":"unable-to-change-mode-of-path-to-0-mode","errorCode":null,"errorMessage":"Unable to change mode of \"{$path}\" to \"0{$mode}\".","messagePattern":"Unable to change mode of \"(.+?)\" to \"0(.+?)\"\\.","errorType":"exception","errorClass":"yii\\base\\Exception","httpStatus":null,"severity":"error","filePath":"framework/helpers/BaseFileHelper.php","lineNumber":1007,"sourceCode":"                $user = $ownerParts[0];\n                if (count($ownerParts) > 1) {\n                    $group = $ownerParts[1];\n                }\n            } elseif (is_array($ownership)) {\n                $ownershipIsIndexed = ArrayHelper::isIndexed($ownership);\n                $user = ArrayHelper::getValue($ownership, $ownershipIsIndexed ? 0 : 'user');\n                $group = ArrayHelper::getValue($ownership, $ownershipIsIndexed ? 1 : 'group');\n            } else {\n                throw new InvalidArgumentException('$ownership must be an integer, string, array, or null.');\n            }\n        }\n\n        if ($mode !== null) {\n            if (!is_int($mode)) {\n                throw new InvalidArgumentException('$mode must be an integer or null.');\n            }\n            if (!chmod($path, $mode)) {\n                throw new Exception('Unable to change mode of \"' . $path . '\" to \"0' . decoct($mode) . '\".');\n            }\n        }\n        if ($user !== null && $user !== '') {\n            if (is_numeric($user)) {\n                $user = (int) $user;\n            } elseif (!is_string($user)) {\n                throw new InvalidArgumentException('The user part of $ownership must be an integer, string, or null.');\n            }\n            if (!chown($path, $user)) {\n                throw new Exception('Unable to change user ownership of \"' . $path . '\" to \"' . $user . '\".');\n            }\n        }\n        if ($group !== null && $group !== '') {\n            if (is_numeric($group)) {\n                $group = (int) $group;\n            } elseif (!is_string($group)) {\n                throw new InvalidArgumentException('The group part of $ownership must be an integer, string or null.');\n            }","sourceCodeStart":989,"sourceCodeEnd":1025,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/helpers/BaseFileHelper.php#L989-L1025","documentation":"After validating that $mode is an int, changeOwnership() calls chmod($path, $mode) and converts a false return into yii\\base\\Exception with the target path and octal mode in the message. Unlike the argument errors, this is an environment/privilege failure: the running PHP process is not the file's owner (and not root), the filesystem is read-only, or a policy (SELinux, mount options) blocks the change.","triggerScenarios":"The web server user (www-data/apache) chmod-ing files created by the deploy user; chmod on a read-only volume or a bind-mount with ro flag; SELinux/AppArmor denying mode changes; FAT/exFAT/NTFS mounts that do not support Unix permission bits.","commonSituations":"Post-deploy fixup steps executed in a web request instead of the deploy pipeline; containers with read-only layers or dropped capabilities; files created by a root CLI script later touched by the web user; Docker volumes mounted from Windows hosts.","solutions":["Run the permission change as the file's owner (or root) — move it to the deploy script/entrypoint instead of application code.","Ensure files are created by the same user that will later chmod them.","Verify the filesystem supports Unix modes and is mounted rw (mount | grep <path>).","Catch yii\\base\\Exception and fail loudly with path and mode in the log rather than ignoring it."],"exampleFix":"// before: runs as www-data, file owned by deployer — chmod fails\n\\yii\\helpers\\FileHelper::changeOwnership(\\Yii::getAlias('@app/runtime/app.log'), null, 0644);\n\n// after: perform in deploy step as the owner\n# deploy.sh (runs as deployer, file owner)\nyii fix-perms/apply","handlingStrategy":"try-catch","validationCode":"// cheap pre-flight: can this process modify the node at all?\nif (!is_writable($path)) {\n    throw new \\RuntimeException(\"Not permitted to chmod: {$path}\");\n}\n\\yii\\helpers\\FileHelper::changeOwnership($path, null, 0644);","typeGuard":null,"tryCatchPattern":"try {\n    \\yii\\helpers\\FileHelper::changeOwnership($path, null, 0644);\n} catch (\\yii\\base\\Exception $e) {\n    // environment failure — report, don't swallow\n    \\Yii::error(\"chmod failed: {$e->getMessage()}\", 'files');\n    throw new \\RuntimeException('Permission fixup failed; run the deploy fix-perms step.', 0, $e);\n}","preventionTips":["Create files with the correct mode at creation time (fopen/mkdir mode) so chmod fixups are rarely needed.","Do permission changes as the file owner in the deploy pipeline, not as the web user at runtime.","Verify filesystems are mounted rw and support POSIX modes before shipping container setups.","Alert on chmod failures — silent skips hide ownership drift."],"tags":["permissions","chmod","privileges","environment","yii2"],"backgroundTag":"chmod-permission-denied","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}