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_bytes() first coerces its argument with RandomCompat_intval(), which throws TypeError for values that cannot be losslessly converted to a non-negative-safe integer (floats with fractions, non-numeric strings, objects, arrays, null). The library catches that internal TypeError and rethrows a clearer one so the caller knows the $bytes parameter itself is bad. This is a fail-fast contract check mirroring PHP 7's native random_bytes() signature.
Solutions
- Cast or validate the length to a positive integer before calling: $len = (int) $len;
- Add a type guard: if (!is_int($len) || $len < 1) { throw new InvalidArgumentException(...); }
- Use RandomCompat_intval() or PHP's is_int()/ctype_digit() checks on any dynamic input.
- Pass a literal integer constant for fixed sizes (e.g. random_bytes(32)).
Example fix
// before
$token = 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');
}
$token = random_bytes($length); Defensive patterns
Strategy: type-guard
Validate before calling
function ensureRandomLength($len) {
if (!is_int($len) || $len < 1) {
throw new InvalidArgumentException('random_bytes length must be a positive integer');
}
return $len;
} Type guard
function isValidRandomLength($len) {
return is_int($len) && $len >= 1;
} Try / catch
try {
$bytes = random_bytes($len);
} catch (TypeError $e) {
// $len was not an integer; log and fail the request
throw new InvalidArgumentException('invalid random_bytes length', 0, $e);
} Prevention
- Never pass raw request input to random_bytes(); cast and validate first.
- Enable PHP 7+ strict_types and scalar type hints (int $len) at call sites.
- Use filter_var($v, FILTER_VALIDATE_INT) for external values.
- Centralize byte-length generation in one helper that validates once.
When it happens
Trigger: Calling random_bytes() with a non-integer value: a numeric string like '10' in strict setups that fail intval conversion, a float such as 10.5, null, a boolean, an array, or an object lacking a valid __toString/to-int path that RandomCompat_intval() rejects.
Common situations: Passing user-supplied request input or unvalidated JSON/GET/POST values straight into random_bytes(); forwarding the result of a calculation that returned null on failure; PHP 5.x polyfill usage where no native type declarations protect the call site.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- RandomCompat_substr(): First argument should be a string
- Length must be greater than 0
- random_bytes(): $bytes must be an integer
- random_bytes(): $bytes must be an integer
- random_int(): $min must be an integer
AI-assisted analysis of paragonie/random_compat@b5d188cc9d (2026-09-13).
Data as JSON: /api/errors/e40f32a75e789801.
Report an issue: GitHub.
Appendix: source
Thrown at lib/random_bytes_com_dotnet.php:47
if (!is_callable('random_bytes')) {
/**
* Windows with PHP < 5.3.0 will not have the function
* openssl_random_pseudo_bytes() available, so let's use
* CAPICOM to work around this deficiency.
*
* @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 */
$buf = '';
if (!class_exists('COM')) {
throw new Error(
'COM does not exist'
);
}
/** @var COM $util */View on GitHub (pinned to b5d188cc9d)