mongodb/laravel-mongodb · error · InvalidArgumentException
Lock lottery must be a couple of integers [$chance, $total]…
Error message
Lock lottery must be a couple of integers [$chance, $total] where $chance <= $total. Example [2, 100]
What it means
MongoLock's constructor validates the optional lottery array used for lock acquisition probabilistics. It must be a two-element array [$chance, $total] of numeric values where the first is <= the second. The library throws InvalidArgumentException in the constructor when the array is malformed, missing elements, or out of order.
Solutions
- Fix the 'lottery' value in config/cache.php (or wherever MongoLock is constructed) to a valid [chance, total] pair like [2, 100]
- Ensure both elements are numeric (int or numeric string) and present
- Ensure chance <= total
- Remove the custom 'lottery' option entirely to use the default [2, 100]
Example fix
// before 'lottery' => [200, 100], // after 'lottery' => [2, 100],
Defensive patterns
Strategy: validation
Validate before calling
$lottery = config('cache.stores.mongodb.lottery', [2, 100]);
assert(is_array($lottery) && count($lottery) === 2 && is_numeric($lottery[0]) && is_numeric($lottery[1]) && $lottery[0] <= $lottery[1]); Type guard
function isValidLottery(mixed $lottery): bool {
return is_array($lottery) && count($lottery) === 2
&& is_numeric($lottery[0]) && is_numeric($lottery[1])
&& $lottery[0] <= $lottery[1];
} Try / catch
try {
$lock = new MongoCacheRepository($store->lock($name, $seconds));
} catch (InvalidArgumentException $e) {
Log::error('Invalid lock lottery config', ['message' => $e->getMessage()]);
$lottery = [2, 100]; // fall back to default
} Prevention
- Keep the default [2, 100] unless you have a measured reason to change it
- Validate the lottery pair in a config bootstrap or phpunit config test
- Never build the lottery array from unvalidated user input
When it happens
Trigger: Passing a 'lottery' config option to the Mongo cache/lock manager with: a non-numeric element (e.g. ['a', 100]), only one element or none ([2] or []), or chance > total (e.g. [200, 100]). The lottery is read from the cache config when instantiating MongoLock in src/Cache/
Common situations: Typo in cache config where 'lottery' is set to a string or single int; copying Laravel database lock lottery config but inverting the values; user attempting to raise lock-obtainment odds by setting a chance larger than the total.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Database is not properly configured.
- MongoDB connection configuration requires "dsn" or "host"…
- The MongoDB Scout collection
AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15).
Data as JSON: /api/errors/561b528ca6679771.
Report an issue: GitHub.
Appendix: source
Thrown at src/Cache/MongoLock.php:35
{
/**
* Create a new lock instance.
*
* @param Collection $collection The MongoDB collection
* @param string $name Name of the lock
* @param int $seconds Time-to-live of the lock in seconds
* @param string|null $owner A unique string that identifies the owner. Random if not set
* @param array{int, int} $lottery Probability [chance, total] of pruning expired cache items. Set to [0, 0] to disable
*/
public function __construct(
private readonly Collection $collection,
string $name,
int $seconds,
?string $owner = null,
private readonly array $lottery = [2, 100],
) {
if (! is_numeric($this->lottery[0] ?? null) || ! is_numeric($this->lottery[1] ?? null) || $this->lottery[0] > $this->lottery[1]) {
throw new InvalidArgumentException('Lock lottery must be a couple of integers [$chance, $total] where $chance <= $total. Example [2, 100]');
}
parent::__construct($name, $seconds, $owner);
}
/**
* Attempt to acquire the lock.
*/
#[Override]
public function acquire(): bool
{
// The lock can be acquired if: it doesn't exist, it has expired,
// or it is already owned by the same lock instance.
$isExpiredOrAlreadyOwned = [
'$or' => [
['$lte' => ['$expires_at', $this->getUTCDateTime()]],
['$eq' => ['$owner', ['$literal' => $this->owner]]],
],View on GitHub (pinned to 0634653039)