{"record":{"id":"b90564e31c772a6d","repo":"cakephp/cakephp","slug":"s-cache-configuration-cannot-fallback-to-itself","errorCode":null,"errorMessage":"`%s` cache configuration cannot fallback to itself.","messagePattern":"`(.+?)` cache configuration cannot fallback to itself\\.","errorType":"validation","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Cache/Cache.php","lineNumber":173,"sourceCode":"\n        $config = static::$_config[$name];\n\n        try {\n            $registry->load($name, $config);\n        } catch (RuntimeException $e) {\n            if (!array_key_exists('fallback', $config)) {\n                $registry->set($name, new NullEngine());\n                trigger_error($e->getMessage(), E_USER_WARNING);\n\n                return;\n            }\n\n            if ($config['fallback'] === false) {\n                throw $e;\n            }\n\n            if ($config['fallback'] === $name) {\n                throw new InvalidArgumentException(sprintf(\n                    '`%s` cache configuration cannot fallback to itself.',\n                    $name,\n                ), 0, $e);\n            }\n\n            $fallbackEngine = clone static::pool($config['fallback']);\n            assert($fallbackEngine instanceof CacheEngine);\n\n            $newConfig = $config + ['groups' => [], 'prefix' => null];\n            $fallbackEngine->setConfig('groups', $newConfig['groups'], false);\n            if ($newConfig['prefix']) {\n                $fallbackEngine->setConfig('prefix', $newConfig['prefix'], false);\n            }\n            $registry->set($name, $fallbackEngine);\n        }\n\n        if ($config['className'] instanceof CacheEngine) {\n            $config = $config['className']->getConfig();","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/cakephp/cakephp/blob/1128eba9b09f1946df684811350e26f2cef68fac/src/Cache/Cache.php#L155-L191","documentation":"When building a cache engine fails, the framework tries the config's `fallback` engine. If `fallback` is set to the same config name, this would recurse infinitely, so _buildEngine throws immediately, chaining the original exception.","triggerScenarios":"Defining a config like Cache::setConfig('redis', ['className' => RedisEngine::class, 'fallback' => 'redis']) and the primary engine failing to build so the fallback path is entered.","commonSituations":"Copy-pasting a config and editing className but forgetting to update fallback; templated config generation where fallback defaults to the same key name; intending fallback to a different engine but pointing it at itself.","solutions":["Set `fallback` to a different, existing config name (e.g. 'default').","If no fallback is wanted, set 'fallback' => false so the original exception propagates.","Verify the fallback target is itself a valid, registered configuration."],"exampleFix":"// before\nCache::setConfig('redis', ['className' => RedisEngine::class, 'fallback' => 'redis']);\n// after\nCache::setConfig('redis', ['className' => RedisEngine::class, 'fallback' => 'default']);","handlingStrategy":"validation","validationCode":"$cfg = Cache::getConfig('redis');\nif ($cfg && ($cfg['fallback'] ?? null) === 'redis') {\n    throw new RuntimeException('fallback must differ from the config name');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $engine = Cache::pool('redis');\n} catch (InvalidArgumentException $e) {\n    $prev = $e->getPrevious();\n    // inspect $prev for the original build failure; fix fallback config before retry\n    throw $prev ?? $e;\n}","preventionTips":["Never template `fallback` from the same variable as the config key.","Set 'fallback' => false when unsure; opt into fallbacks deliberately.","Ensure the fallback target is a simple, always-available engine (e.g. FileEngine).","Add a config lint step asserting fallback names differ from their own keys and exist."],"tags":["cache","configuration","fallback"],"backgroundTag":"conflicting-config-options","analyzedSha":"1128eba9b09f1946df684811350e26f2cef68fac","analyzedAt":"2026-09-12T12:07:00.388Z","contentChangedAt":"2026-09-12T12:07:00.388Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}