laravel/framework · warning · RuntimeException

Flushing locks is only supported when the lock store is sepa

Error message

Flushing locks is only supported when the lock store is separate from the cache store.

What it means

FileStore::flushLocks() throws if hasSeparateLockStore() is false, i.e. when lockDirectory is null or equals the cache directory. Without a distinct lock directory, flushing only locks would require distinguishing lock files from cache files, which the store does not support.

Source

Thrown at src/Illuminate/Cache/FileStore.php:370

            if (! $deleted || $this->files->exists($directory)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Remove all locks from the store.
     *
     * @return bool
     *
     * @throws \RuntimeException
     */
    public function flushLocks(): bool
    {
        if (! $this->hasSeparateLockStore()) {
            throw new RuntimeException('Flushing locks is only supported when the lock store is separate from the cache store.');
        }

        if (! $this->files->isDirectory($this->lockDirectory)) {
            return false;
        }

        foreach ($this->files->directories($this->lockDirectory) as $lockDirectory) {
            $deleted = $this->files->deleteDirectory($lockDirectory);

            if (! $deleted || $this->files->exists($lockDirectory)) {
                return false;
            }
        }

        return true;
    }

    /**

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Add 'lock_path' => storage_path('framework/cache/locks') (different from 'path') in the file store config.
  2. Ensure the lock directory exists and is writable (chmod, storage:bootstrap).
  3. If a single directory is intentional, call flush() to clear everything instead of flushLocks().

Example fix

// before
'file' => [
    'driver' => 'file',
    'path' => storage_path('framework/cache/data'),
    // no lock_path -> flushLocks throws
],

// after
'file' => [
    'driver' => 'file',
    'path' => storage_path('framework/cache/data'),
    'lock_path' => storage_path('framework/cache/locks'),
],
Defensive patterns

Strategy: validation

Validate before calling

$store = Cache::store('file')->getStore();
if ($store instanceof \Illuminate\Cache\FileStore && ! $store->hasSeparateLockStore()) {
    throw new \RuntimeException('File cache requires a distinct lock_path to flushLocks().');
}
$store->flushLocks();

Type guard

function fileCacheHasSeparateLocks(\Illuminate\Contracts\Cache\Store $store): bool
{
    return $store instanceof \Illuminate\Cache\FileStore
        && $store->hasSeparateLockStore();
}

Try / catch

try {
    Cache::store('file')->getStore()->flushLocks();
} catch (\RuntimeException $e) {
    if (str_contains($e->getMessage(), 'lock store is separate')) {
        Cache::store('file')->flush();
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Configuring a file cache store without 'lock_path', then calling Cache::store('file')->getStore()->flushLocks() or cache:clear-locks. The guard fires whenever lockDirectory is null or identical to the main directory.

Common situations: Default file store config omits lock_path. Sharing one cache directory for both values and locks. Older Laravel upgrades where lock_path did not exist.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/f0d09aefca4e1311.json. Report an issue: GitHub.