laravel/framework · error · InvalidArgumentException
The seed value must be numeric.
Error message
The seed value must be numeric.
What it means
MySqlGrammar's compileRandom accepts a seed value for RAND(seed). If the seed is not empty/null (which produces RAND()) and is not numeric (fails is_numeric()), it throws an InvalidArgumentException. MySQL's RAND() accepts only an integer seed, so non-numeric seeds are rejected.
Solutions
- Call ->inRandomOrder() with no argument to use RAND() without a seed
- Pass an integer seed: ->inRandomOrder(42) or ->inRandomOrder((int) $seed)
- Validate the seed before passing: if (is_numeric($seed)) { $query->inRandomOrder($seed); } else { $query->inRandomOrder(); }
Example fix
// before — non-numeric seed throws
$results = Product::inRandomOrder($request->input('seed', 'abc'))->get();
// after — cast or default to null
$seed = $request->input('seed');
$results = Product::inRandomOrder(is_numeric($seed) ? (int) $seed : null)->get(); Defensive patterns
Strategy: validation
Validate before calling
$seed = $request->input('seed');
if ($seed === null || $seed === '' || ! is_numeric($seed)) {
$results = Product::inRandomOrder()->get();
} else {
$results = Product::inRandomOrder((int) $seed)->get();
} Type guard
function isValidRandomSeed(mixed $seed): bool {
return $seed === null || $seed === '' || is_numeric($seed);
} Try / catch
try {
Product::inRandomOrder($seed)->get();
} catch (\InvalidArgumentException $e) {
if (str_contains($e->getMessage(), 'seed value must be numeric')) {
Product::inRandomOrder()->get();
} else {
throw $e;
}
} Prevention
- Call inRandomOrder() without arguments unless you specifically need a reproducible seed
- Validate user-supplied seeds with is_numeric() before passing to inRandomOrder()
- Cast seeds to int: inRandomOrder((int) $seed) to satisfy MySQL's RAND(N) requirement
When it happens
Trigger: Calling ->inRandomOrder('abc') or ->inRandomOrder($stringVar) where $stringVar is a non-numeric string. Also triggered if inRandomOrder receives an array or object.
Common situations: Passing a string-based seed (e.g., a UUID or session token) to inRandomOrder thinking it acts as a hash-based seed. Dynamically passing user input as a seed without validation. Passing a float string like '1.5' works (is_numeric returns true), but truly non-numeric strings fail.
Related errors
- Index name contains invalid characters.
- Add fillable property
- Collection given to whereAttachedTo method may not be empty.
- Collection given to whereBelongsTo method may not be empty.
- Collection given to whereMorphedTo method may not be empty.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/e621b23ecc9b6027.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Query/Grammars/MySqlGrammar.php:347
return 'cast('.$value.' as json)';
}
/**
* Compile the random statement into SQL.
*
* @param string|int $seed
* @return string
*
* @throws \InvalidArgumentException
*/
public function compileRandom($seed)
{
if ($seed === '' || $seed === null) {
return 'RAND()';
}
if (! is_numeric($seed)) {
throw new InvalidArgumentException('The seed value must be numeric.');
}
return 'RAND('.(int) $seed.')';
}
/**
* Compile the lock into SQL.
*
* @param \Illuminate\Database\Query\Builder $query
* @param bool|string $value
* @return string
*/
protected function compileLock(Builder $query, $value)
{
if (! is_string($value)) {
return $value ? 'for update' : 'lock in share mode';
}
View on GitHub (pinned to e0f6eb3518)