{"record":{"id":"691fe2d0a423641e","repo":"laravel/framework","slug":"this-lock-driver-does-not-support-refreshing-locks","errorCode":null,"errorMessage":"This lock driver does not support refreshing locks.","messagePattern":"This lock driver does not support refreshing locks\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"src/Illuminate/Cache/Lock.php","lineNumber":149,"sourceCode":"            try {\n                return $callback();\n            } finally {\n                $this->release();\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Attempt to refresh the lock for the given number of seconds.\n     *\n     * @param  int|null  $seconds\n     * @return bool\n     */\n    public function refresh($seconds = null)\n    {\n        throw new RuntimeException('This lock driver does not support refreshing locks.');\n    }\n\n    /**\n     * Returns the current owner of the lock.\n     *\n     * @return string\n     */\n    public function owner()\n    {\n        return $this->owner;\n    }\n\n    /**\n     * Determine if the lock is currently held by any process.\n     *\n     * @return bool\n     */\n    public function isLocked(): bool","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Cache/Lock.php#L131-L167","documentation":"The base Lock::refresh is a stub that always throws. Subclasses with refresh support (e.g., RedisLock, DatabaseLock) override this method to extend the TTL atomically. If you call refresh() on a lock instance whose driver does not override it, you hit the base implementation. This signals that the underlying store cannot safely extend a lock without re-acquiring it.","triggerScenarios":"Calling $lock->refresh(60) on a lock acquired from a driver that doesn't support TTL extension (e.g., ArrayLock, or custom Lock subclass without overriding refresh). Also when calling refresh() on a lock restored via restoreLock() that lost its concrete subclass.","commonSituations":"Code designed for RedisLock deployed against the array driver in tests. Custom lock implementations that subclass Lock but forget to override refresh(). Long-running jobs that try to extend their lock mid-execution on an unsupported driver.","solutions":["Switch to a driver whose Lock subclass overrides refresh(): RedisLock or DatabaseLock.","Re-acquire instead of refresh: release() the current lock and acquire() a new one with the desired TTL.","If authoring a custom Lock, override refresh($seconds = null) to atomically extend the TTL (e.g., via EXPIRE with owner token check)."],"exampleFix":"// before\n$lock = Cache::lock('process-' . $id, 30);\n// long-running work on array driver\n$lock->refresh(30); // RuntimeException\n\n// after - re-acquire\n$lock->release();\n$lock = Cache::block('process-' . $id, 30, function () {\n    // continue work\n});\n// OR use a driver that supports refresh:\n// CACHE_LOCK_STORE=redis","handlingStrategy":"validation","validationCode":"// Validate the lock supports refresh before calling\n$lock = Cache::lock('job-' . $id, 30);\n$reflector = new \\ReflectionMethod($lock, 'refresh');\nif ($reflector->getDeclaringClass()->getName() === \\Illuminate\\Cache\\Lock::class) {\n    // base stub would throw; re-acquire instead\n    $lock->release();\n    $lock = Cache::lock('job-' . $id, 30);\n} else {\n    $lock->refresh(30);\n}","typeGuard":"function lockSupportsRefresh(\\Illuminate\\Contracts\\Cache\\Lock $lock): bool\n{\n    return (new \\ReflectionMethod($lock, 'refresh'))\n        ->getDeclaringClass()\n        ->getName() !== \\Illuminate\\Cache\\Lock::class;\n}","tryCatchPattern":"try {\n    $lock->refresh(30);\n} catch (\\RuntimeException $e) {\n    if (str_contains($e->getMessage(), 'does not support refreshing locks')) {\n        // fall back: release and re-acquire\n        $lock->release();\n        $lock = Cache::lock($lock->owner() ? 'job-' . $id : 'job-' . $id, 30)->block(5);\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Standardize on RedisLock or DatabaseLock when code calls refresh().","Add a project helper refreshLock($lock, $ttl) that branches on driver capability.","When authoring custom Lock subclasses, override refresh() to extend TTL atomically.","Test lock behavior against the same driver used in production."],"tags":["cache","locks","unsupported-operation"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}