paragonie/random_compat · error · TypeError
random_bytes(): $bytes must be an integer
Error message
random_bytes(): $bytes must be an integer
What it means
random_compat's libsodium-legacy random_bytes() first coerces its $bytes argument with RandomCompat_intval(); if the value cannot be represented as an integer (floats with fractional parts, non-numeric strings, objects), a TypeError is caught and re-thrown with this message. The library enforces strict integer input even on PHP 5, mirroring PHP 7's random_bytes() signature.
Solutions
- Cast the argument explicitly to int before calling: random_bytes((int) $length).
- Validate the input is a whole number (is_int() or ctype_digit for strings) before calling.
- If the value comes from user input, reject non-numeric input rather than silently casting.
- Update code paths that compute lengths with float math to use intval() or (int) casts.
Example fix
// before
$bytes = random_bytes($_GET['length']);
// after
$length = filter_var($_GET['length'], FILTER_VALIDATE_INT);
if ($length === false || $length < 1) {
throw new InvalidArgumentException('length must be a positive integer');
}
$bytes = random_bytes($length); Defensive patterns
Strategy: type-guard
Validate before calling
function isValidByteLength($n): bool {
return is_int($n) && $n >= 1;
} Type guard
function asByteCount($n): ?int {
if (is_int($n) && $n >= 1) return $n;
if (is_string($n) && ctype_digit($n)) return (int) $n;
return null; // caller must handle
} Try / catch
try {
$bytes = random_bytes($length);
} catch (TypeError $e) {
throw new InvalidArgumentException('$length must be an integer >= 1', 0, $e);
} Prevention
- Cast lengths with (int) only after validating the raw value is numeric.
- Use filter_var($v, FILTER_VALIDATE_INT) for user-supplied lengths.
- On PHP 7+, add int type declarations to wrapper functions.
- Never pass untyped superglobal values directly to random_bytes().
When it happens
Trigger: Calling random_bytes() with a non-integer value such as '32', 32.5, null, or an array — RandomCompat_intval() throws and lib/random_bytes_libsodium_legacy.php:49 rethrows as TypeError.
Common situations: Passing a string from user input or a config file without casting, passing the result of division on PHP 5 where floats are common, or passing null from an uninitialized variable.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- random_bytes(): $bytes must be an integer
- random_int(): $min must be an integer
- random_int(): $max must be an integer
- RandomCompat_substr(): First argument should be a string
- RandomCompat_strlen() expects a string
AI-assisted analysis of paragonie/random_compat@b5d188cc9d (2026-09-13).
Data as JSON: /api/errors/ec71e01e4a115966.
Report an issue: GitHub.
Appendix: source
Thrown at lib/random_bytes_libsodium_legacy.php:49
* If the libsodium PHP extension is loaded, we'll use it above any other
* solution.
*
* libsodium-php project:
* @ref https://github.com/jedisct1/libsodium-php
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
/** @var int $bytes */
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/**
* @var string
*/
$buf = '';
/**
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
* generated in one invocation.View on GitHub (pinned to b5d188cc9d)