yiisoft/yii2 · error · yii\base\InvalidArgumentException
The group part of $ownership must be an integer, string or n
Error message
The group part of $ownership must be an integer, string or null.
What it means
The mirror of the user-side check inside changeOwnership(): the extracted 'group' part must be numeric-coercible, a string, or null. An array or object in the group slot throws InvalidArgumentException before chgrp() runs. It reports a malformed ownership argument, not a filesystem failure.
Source
Thrown at framework/helpers/BaseFileHelper.php:1024
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.');
}
if (!chgrp($path, $group)) {
throw new Exception('Unable to change group ownership of "' . $path . '" to "' . $group . '".');
}
}
}
}
View on GitHub (pinned to 66f00d18a2)
Solutions
- Flatten config so 'group' maps to a scalar (name or gid).
- Validate the extracted group: is_numeric($group) || is_string($group) || $group === null.
- Cast numeric strings to int before the call.
Example fix
// before \yii\helpers\FileHelper::changeOwnership($file, ['user' => 'www-data', 'group' => ['gid' => 33]]); // after \yii\helpers\FileHelper::changeOwnership($file, ['user' => 'www-data', 'group' => 33]);
Defensive patterns
Strategy: type-guard
Validate before calling
$group = is_array($ownership) ? ($ownership['group'] ?? null) : null;
if (!(is_numeric($group) || is_string($group) || $group === null)) {
throw new \InvalidArgumentException('Ownership group part must be scalar');
} Type guard
/** @param mixed $group */
function isGroupPart($group): bool
{
return $group === null || $group === '' || is_numeric($group) || is_string($group);
} Prevention
- Keep the 'group' key in ownership config a scalar (name or gid).
- Validate the whole ownership structure once, at config load, not at each call site.
- Add config schema tests asserting scalar types for user/group.
When it happens
Trigger: ['group' => ['gid' => 33]]; the string form 'user:' combined with a downstream lookup that injects an array; indexed form [0 => 'www-data', 1 => ['gid' => 33]] with an array in the group slot.
Common situations: Structured config (YAML maps) for group ownership; ownership values merged from multiple config sources where one side supplies an array; API-driven ownership data with unknown shape.
Related errors
- $ownership must be an integer, string, array, or null.
- The user part of $ownership must be an integer, string, or n
- Exclude/include pattern must be a string.
- Unable to change ownership, "{$path}" is not a file or direc
- $mode must be an integer or null.
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/176ba9395aa277ad.
Report an issue: GitHub.