yiisoft/yii2 · error · InvalidArgumentException
First parameter ($length) must be greater than 0
Error message
First parameter ($length) must be greater than 0
What it means
generateRandomKey() requires $length >= 1 so random_bytes() is never invoked with a zero or negative count. Reaching this exception means an integer 0 or negative value was passed — typically a computed size that legitimately evaluated to 0 (empty input, block-aligned data) rather than a typo.
Source
Thrown at framework/base/Security.php:412
/**
* Generates specified number of random bytes.
* Note that output may not be ASCII.
* @see generateRandomString() if you need a string.
*
* @param int $length the number of bytes to generate
* @return string the generated random bytes
* @throws InvalidArgumentException if wrong length is specified
* @throws Exception on failure.
*/
public function generateRandomKey($length = 32)
{
if (!is_int($length)) {
throw new InvalidArgumentException('First parameter ($length) must be an integer');
}
if ($length < 1) {
throw new InvalidArgumentException('First parameter ($length) must be greater than 0');
}
return random_bytes($length);
}
/**
* Generates a random string of specified length.
* The string generated matches [A-Za-z0-9_-]+ and is transparent to URL-encoding.
*
* @param int $length the length of the key in characters
* @return string the generated random key
* @throws Exception on failure.
*/
public function generateRandomString($length = 32)
{
if (!is_int($length)) {
throw new InvalidArgumentException('First parameter ($length) must be an integer');
}View on GitHub (pinned to 66f00d18a2)
Solutions
- Guard computed sizes: max(1, $computed) when at least one byte is acceptable, or skip the call entirely when 0 is the correct answer
- Fix operand order in size arithmetic ($total - $used vs $used - $total)
- Validate config-driven sizes as >= 1 at bootstrap
- Cover the edge lengths (0, 1, boundary) in unit tests for code that computes sizes
Example fix
// before $padding = $blockSize - (strlen($data) % $blockSize); $salt = Yii::$app->security->generateRandomKey($padding); // 0 when data is block-aligned → exception // after $padding = $blockSize - (strlen($data) % $blockSize); $salt = $padding >= 1 ? Yii::$app->security->generateRandomKey($padding) : '';
Defensive patterns
Strategy: validation
Validate before calling
$length = (int) $computed;
if ($length < 1) {
throw new \InvalidArgumentException('Computed random key length must be >= 1, got ' . $computed);
}
$bytes = Yii::$app->security->generateRandomKey($length); Type guard
function isPositiveIntLength($length): bool
{
return is_int($length) && $length >= 1;
} Prevention
- Treat a computed length of 0 as a no-op and skip the call rather than passing it down
- Unit-test boundary lengths (0, 1, block size) in code that derives sizes arithmetically
- Reject zero/negative lengths with input validation before they reach Security
When it happens
Trigger: Padding computed as $blockSize - (strlen($data) % $blockSize) hitting 0 for block-aligned data; generateRandomKey(count($items)) with an empty collection; subtraction with swapped operands yielding a negative; config values defaulting to 0.
Common situations: Cryptographic padding/salt code paths that only fail for certain input lengths; optional inputs where an empty selection produces length 0; off-by-one or operand-order arithmetic bugs.
Related errors
- First parameter ($length) must be an integer
- Password must be a string and cannot be empty.
- Encryption requires the OpenSSL PHP extension
- {cipher} is not an allowed cipher
- Invalid parameters to hash_hkdf()
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/163e95330f7f5dca.
Report an issue: GitHub.