paragonie/random_compat · error · TypeError
Expected an integer.
Error message
Expected an integer.
What it means
RandomCompat_intval() is the library's strict integer coercion helper. After attempting casts (floats, numeric strings, objects with known representations), if the value still is not an int and $fail_open is false, it throws a TypeError('Expected an integer.'). It guards random_int() and internal callers against non-integer inputs.
Solutions
- Validate and cast bounds before the call: random_int((int) $min, (int) $max) — only after confirming the value is genuinely numeric.
- Use is_int()/is_numeric() checks on inputs from HTTP/JSON sources and reject non-integers with a 400-style response.
- If you intended float math, use a non-cryptographic function instead; random_int only accepts integers.
Example fix
// before
$n = random_int($_GET['min'], $_GET['max']);
// after
$min = filter_var($_GET['min'], FILTER_VALIDATE_INT);
$max = filter_var($_GET['max'], FILTER_VALIDATE_INT);
if ($min === false || $max === false) {
throw new InvalidArgumentException('min/max must be integers');
}
$n = random_int($min, $max); Defensive patterns
Strategy: validation
Validate before calling
// before calling random_int
$min = filter_var($rawMin, FILTER_VALIDATE_INT);
$max = filter_var($rawMax, FILTER_VALIDATE_INT);
if ($min === false || $max === false || $min > $max) {
throw new InvalidArgumentException('Bounds must be integers with min <= max');
} Type guard
function asIntOrNull($value) {
if (is_int($value)) return $value;
if (is_string($value) && preg_match('/^-?\d+$/', $value)) return (int) $value;
return null;
} Try / catch
try {
$n = random_int($min, $max);
} catch (TypeError $e) {
// input was not an integer: reject the request, do not retry blindly
throw new InvalidArgumentException('random_int bounds must be integers', 0, $e);
} catch (Exception $e) {
// entropy source failure — handle separately
} Prevention
- Never pass superglobal values ($_GET/$_POST) directly to random_int
- JSON-decode with options and validate numeric fields are ints before use
- Keep min <= max and within PHP_INT range before the call
When it happens
Trigger: Calling random_int($min, $max) with arguments that cannot be losslessly interpreted as integers: non-numeric strings ('abc'), floats with fractional parts (1.5), true/false, arrays, null, or objects; also passing values exceeding the integer size limits that fail the strict conversion.
Common situations: Bounds sourced from user input ($_GET['min']), JSON-decoded values that are strings, database BIGINT columns returned as strings on PHP 5, or accidental use of a float constant like M_PI as a bound.
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_strlen() expects a string
- RandomCompat_substr(): First argument should be a string
- RandomCompat_substr(): Second argument should be an integer
- RandomCompat_substr(): Third argument should be an integer…
- random_bytes(): $bytes must be an integer
AI-assisted analysis of paragonie/random_compat@b5d188cc9d (2026-09-13).
Data as JSON: /api/errors/92a90f4443a4eb14.
Report an issue: GitHub.
Appendix: source
Thrown at lib/cast_to_int.php:71
/** @psalm-suppress InvalidOperand */
$number += 0;
}
/** @var int|float $number */
if (
is_float($number)
&&
$number > ~PHP_INT_MAX
&&
$number < PHP_INT_MAX
) {
$number = (int) $number;
}
if (is_int($number)) {
return (int) $number;
} elseif (!$fail_open) {
throw new TypeError(
'Expected an integer.'
);
}
return $number;
}
}
View on GitHub (pinned to b5d188cc9d)