{"record":{"id":"059e08b8e798177e","repo":"yiisoft/yii2","slug":"first-parameter-length-must-be-an-integer","errorCode":null,"errorMessage":"First parameter ($length) must be an integer","messagePattern":"First parameter \\(\\$length\\) must be an integer","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"framework/base/Security.php","lineNumber":408,"sourceCode":"        }\n\n        return false;\n    }\n\n    /**\n     * Generates specified number of random bytes.\n     * Note that output may not be ASCII.\n     * @see generateRandomString() if you need a string.\n     *\n     * @param int $length the number of bytes to generate\n     * @return string the generated random bytes\n     * @throws InvalidArgumentException if wrong length is specified\n     * @throws Exception on failure.\n     */\n    public function generateRandomKey($length = 32)\n    {\n        if (!is_int($length)) {\n            throw new InvalidArgumentException('First parameter ($length) must be an integer');\n        }\n\n        if ($length < 1) {\n            throw new InvalidArgumentException('First parameter ($length) must be greater than 0');\n        }\n\n        return random_bytes($length);\n    }\n\n    /**\n     * Generates a random string of specified length.\n     * The string generated matches [A-Za-z0-9_-]+ and is transparent to URL-encoding.\n     *\n     * @param int $length the length of the key in characters\n     * @return string the generated random key\n     * @throws Exception on failure.\n     */\n    public function generateRandomString($length = 32)","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/base/Security.php#L390-L426","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n$bytes = Yii::$app->security->generateRandomKey(Yii::$app->params['keyBytes']); // '32' (string) → exception\n\n// after\n$bytes = Yii::$app->security->generateRandomKey((int) Yii::$app->params['keyBytes']);","handlingStrategy":"type-guard","validationCode":"$length = (int) $length;\nif ($length < 1) {\n    $length = 32;\n}\n$bytes = Yii::$app->security->generateRandomKey($length);","typeGuard":"function isPositiveIntLength($length): bool\n{\n    return is_int($length) && $length >= 1;\n}","tryCatchPattern":null,"preventionTips":["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)"],"tags":["php","yii2","security","random","type-error"],"backgroundTag":"string-where-int-expected","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}