laravel/framework · warning · BadMethodCallException

This cache store does not support locks.

Error message

This cache store does not support locks.

What it means

MemoizedStore wraps an underlying Repository and delegates lock() to it. If the wrapped store does not implement Illuminate\Contracts\Cache\LockProvider, no locks are available and the call is refused with BadMethodCallException. The memoized layer itself has no lock semantics; it depends entirely on the underlying store.

Solutions

  1. Call lock() on the underlying non-memoized store: Cache::store('redis')->lock('key') instead of Cache::memo()->lock('key').
  2. Switch the memoized driver's underlying store to one implementing LockProvider (redis, database, memcached, file).
  3. Guard calls with Cache::memo()->getStore() instanceof LockProvider before invoking lock().

Example fix

// before
Cache::memo()->lock('export-' . $user->id, 60);
// underlying store is 'array' -> BadMethodCallException

// after
if (Cache::store(config('cache.memo'))->getStore() instanceof \Illuminate\Contracts\Cache\LockProvider) {
    Cache::store(config('cache.memo'))->lock('export-' . $user->id, 60)->block(5);
} else {
    Cache::store('redis')->lock('export-' . $user->id, 60)->block(5);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate the memoized store's underlying store supports locks before calling lock()
$store = Cache::memo()->getStore();
if (! $store->getRepository()->getStore() instanceof \Illuminate\Contracts\Cache\LockProvider) {
    throw new \RuntimeException('Underlying memo store does not support locks.');
}
$store->lock('key', 60);

Type guard

function memoStoreSupportsLocks(\Illuminate\Cache\Repository $repo): bool
{
    return $repo->getStore() instanceof \Illuminate\Contracts\Cache\LockProvider;
}

Try / catch

try {
    Cache::memo()->lock('key', 60);
} catch (\BadMethodCallException $e) {
    if (str_contains($e->getMessage(), 'does not support locks')) {
        // fall back to a lock-supporting store
        return Cache::store('redis')->lock('key', 60);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling Cache::memo()->lock('key') or any code path that obtains the memoized repository and calls ->lock() when the underlying driver (e.g., array, dynamodb without lock support, null driver) does not implement LockProvider.

Common situations: Test code using Cache::memo() with CACHE_DRIVER=array and attempting to acquire a lock. Production code that calls Cache::memo()->lock() on a driver like 'file' or 'dynamodb' that does provide locks via a different interface but the memo wrapper check is strict on LockProvider.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/75c936a1a7cba417. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Cache/MemoizedStore.php:176

        unset($this->cache[$this->prefix($key)]);

        return $this->repository->forever($key, $value);
    }

    /**
     * Get a lock instance.
     *
     * @param  string  $name
     * @param  int  $seconds
     * @param  string|null  $owner
     * @return \Illuminate\Contracts\Cache\Lock
     *
     * @throws \BadMethodCallException
     */
    public function lock($name, $seconds = 0, $owner = null)
    {
        if (! $this->repository->getStore() instanceof LockProvider) {
            throw new BadMethodCallException('This cache store does not support locks.');
        }

        return $this->repository->getStore()->lock(...func_get_args());
    }

    /**
     * Restore a lock instance using the owner identifier.
     *
     * @param  string  $name
     * @param  string  $owner
     * @return \Illuminate\Contracts\Cache\Lock
     *
     * @throws \BadMethodCallException
     */
    public function restoreLock($name, $owner)
    {
        if (! $this->repository->getStore() instanceof LockProvider) {
            throw new BadMethodCallException('This cache store does not support locks.');

View on GitHub (pinned to e0f6eb3518)