yiisoft/yii2 · error · yii\base\Exception

Unable to change mode of "{$path}" to "0{$mode}".

Error message

Unable to change mode of "{$path}" to "0{$mode}".

What it means

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.

Source

Thrown at framework/helpers/BaseFileHelper.php:1007

                $user = $ownerParts[0];
                if (count($ownerParts) > 1) {
                    $group = $ownerParts[1];
                }
            } elseif (is_array($ownership)) {
                $ownershipIsIndexed = ArrayHelper::isIndexed($ownership);
                $user = ArrayHelper::getValue($ownership, $ownershipIsIndexed ? 0 : 'user');
                $group = ArrayHelper::getValue($ownership, $ownershipIsIndexed ? 1 : 'group');
            } else {
                throw new InvalidArgumentException('$ownership must be an integer, string, array, or null.');
            }
        }

        if ($mode !== null) {
            if (!is_int($mode)) {
                throw new InvalidArgumentException('$mode must be an integer or null.');
            }
            if (!chmod($path, $mode)) {
                throw new Exception('Unable to change mode of "' . $path . '" to "0' . decoct($mode) . '".');
            }
        }
        if ($user !== null && $user !== '') {
            if (is_numeric($user)) {
                $user = (int) $user;
            } elseif (!is_string($user)) {
                throw new InvalidArgumentException('The user part of $ownership must be an integer, string, or null.');
            }
            if (!chown($path, $user)) {
                throw new Exception('Unable to change user ownership of "' . $path . '" to "' . $user . '".');
            }
        }
        if ($group !== null && $group !== '') {
            if (is_numeric($group)) {
                $group = (int) $group;
            } elseif (!is_string($group)) {
                throw new InvalidArgumentException('The group part of $ownership must be an integer, string or null.');
            }

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Run the permission change as the file's owner (or root) — move it to the deploy script/entrypoint instead of application code.
  2. Ensure files are created by the same user that will later chmod them.
  3. Verify the filesystem supports Unix modes and is mounted rw (mount | grep <path>).
  4. Catch yii\base\Exception and fail loudly with path and mode in the log rather than ignoring it.

Example fix

// before: runs as www-data, file owned by deployer — chmod fails
\yii\helpers\FileHelper::changeOwnership(\Yii::getAlias('@app/runtime/app.log'), null, 0644);

// after: perform in deploy step as the owner
# deploy.sh (runs as deployer, file owner)
yii fix-perms/apply
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap pre-flight: can this process modify the node at all?
if (!is_writable($path)) {
    throw new \RuntimeException("Not permitted to chmod: {$path}");
}
\yii\helpers\FileHelper::changeOwnership($path, null, 0644);

Try / catch

try {
    \yii\helpers\FileHelper::changeOwnership($path, null, 0644);
} catch (\yii\base\Exception $e) {
    // environment failure — report, don't swallow
    \Yii::error("chmod failed: {$e->getMessage()}", 'files');
    throw new \RuntimeException('Permission fixup failed; run the deploy fix-perms step.', 0, $e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/49cbeee2580149fb. Report an issue: GitHub.