yiisoft/yii2 · error · InvalidArgumentException
First parameter ($length) must be an integer
Error message
First parameter ($length) must be an integer
What it means
Security::generateRandomKey() has no parameter type declaration and guards its input manually: is_int($length) fails for strings, floats, and null, throwing InvalidArgumentException before random_bytes() is reached. Numeric-looking values like '32' (string) or 32.0 (float) are rejected because PHP performs no coercion here.
Source
Thrown at framework/base/Security.php:408
}
return false;
}
/**
* 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)View on GitHub (pinned to 66f00d18a2)
Solutions
- Cast at the call site: generateRandomKey((int) $size)
- Normalize config once at read time so downstream code always sees ints
- For nullable sources, coalesce before the call: (int) ($size ?? 32)
- Watch for float results of division/multiplication — round or cast explicitly
Example fix
// before $bytes = Yii::$app->security->generateRandomKey(Yii::$app->params['keyBytes']); // '32' (string) → exception // after $bytes = Yii::$app->security->generateRandomKey((int) Yii::$app->params['keyBytes']);
Defensive patterns
Strategy: type-guard
Validate before calling
$length = (int) $length;
if ($length < 1) {
$length = 32;
}
$bytes = Yii::$app->security->generateRandomKey($length); Type guard
function isPositiveIntLength($length): bool
{
return is_int($length) && $length >= 1;
} Prevention
- Cast length parameters to int at the boundary where they enter your code
- Store numeric config as real numbers, or normalize config values once at load
- Coalesce nullable sources: (int) ($size ?? 32)
When it happens
Trigger: Length read from JSON/env/config as a string ('16'); a float produced by arithmetic (16.0 fails is_int); null passed by a wrapper's default instead of relying on the method's own default 32; values forwarded from loosely typed request params.
Common situations: Config-driven key/salt sizes stored as strings; shared helper code mixing strict and loose callers; parameters crossing a JSON boundary and losing their type.
Related errors
- First parameter ($length) must be greater than 0
- Encryption requires the OpenSSL PHP extension
- {cipher} is not an allowed cipher
- Invalid parameters to hash_hkdf()
- Invalid parameters to hash_pbkdf2()
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/059e08b8e798177e.
Report an issue: GitHub.