{"record":{"id":"5e1e144fa120de9f","repo":"doctrine/cache","slug":"cache-key-length-must-be-greater-than-zero","errorCode":null,"errorMessage":"Cache key length must be greater than zero.","messagePattern":"Cache key length must be greater than zero\\.","errorType":"exception","errorClass":"InvalidArgument","httpStatus":null,"severity":"error","filePath":"lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php","lineNumber":261,"sourceCode":"        return $success;\n    }\n\n    public function __destruct()\n    {\n        $this->commit();\n    }\n\n    /**\n     * @param mixed $key\n     */\n    private static function validKey($key): bool\n    {\n        if (! is_string($key)) {\n            throw new InvalidArgument(sprintf('Cache key must be string, \"%s\" given.', is_object($key) ? get_class($key) : gettype($key)));\n        }\n\n        if ($key === '') {\n            throw new InvalidArgument('Cache key length must be greater than zero.');\n        }\n\n        if (strpbrk($key, self::RESERVED_CHARACTERS) !== false) {\n            throw new InvalidArgument(sprintf('Cache key \"%s\" contains reserved characters \"%s\".', $key, self::RESERVED_CHARACTERS));\n        }\n\n        return true;\n    }\n\n    /**\n     * @param mixed[] $keys\n     */\n    private static function validKeys(array $keys): bool\n    {\n        foreach ($keys as $key) {\n            self::validKey($key);\n        }\n","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/doctrine/cache/blob/e0a9919443c1e918251c23b65eddd9a66fafacb3/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php#L243-L279","documentation":"PSR-6 and Doctrine's adapter forbid empty-string cache keys. validKey() throws InvalidArgument when a '' string is passed to getItem, hasItem, deleteItem, deleteItems or validKeys, because an empty key cannot be stored or looked up meaningfully.","triggerScenarios":"Calling any pool method with a key that is the empty string, typically a variable produced by concatenating missing parts or trimming a value down to nothing.","commonSituations":"Configuration field left blank ('') used directly as a cache key prefix; sprintf/implode producing '' when inputs are absent; trim() of whitespace-only input.","solutions":["Ensure a non-empty fallback or prefix is used, e.g. $key !== '' ?: 'default'","Validate/trim and reject empty keys at the application boundary before caching","Log or skip caching when the computed key is empty instead of calling the pool"],"exampleFix":"// before\n$item = $pool->getItem(trim($userInput));\n// after\n$key = trim($userInput);\nif ($key === '') { throw new InvalidArgumentException('Cache key cannot be empty'); }\n$item = $pool->getItem($key);","handlingStrategy":"validation","validationCode":"if (!is_string($key) || $key === '') { throw new InvalidArgumentException('Cache key must be a non-empty string'); }","typeGuard":"function isValidCacheKey(mixed $key): bool { return is_string($key) && $key !== ''; }","tryCatchPattern":"try { return $pool->getItem($key); } catch (\\Doctrine\\Common\\Cache\\Psr6\\InvalidArgument $e) { return null; }","preventionTips":["Add default fallbacks for empty config-driven key prefixes","Validate computed keys before caching","Fail fast on empty input instead of silently producing an empty key"],"tags":["php","psr6","cache","empty-string"],"backgroundTag":"empty-required-field","analyzedSha":"e0a9919443c1e918251c23b65eddd9a66fafacb3","analyzedAt":"2026-09-13T19:23:46.714Z","contentChangedAt":"2026-09-13T19:23:46.714Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}