{"record":{"id":"d4eb9459a2dffd83","repo":"phalcon/cphalcon","slug":"circular-alias-detected-name","errorCode":null,"errorMessage":"Circular alias detected: '{name}'","messagePattern":"Circular alias detected: '(.+?)'","errorType":"exception","errorClass":"Phalcon\\Container\\Exceptions\\CircularAliasFound","httpStatus":null,"severity":"error","filePath":"phalcon/Container/Container.zep","lineNumber":765,"sourceCode":"\n    /**\n     * Resolve an alias\n     *\n     * @param string $name\n     *\n     * @return string\n     * @throws CircularAliasFound\n     */\n    private function resolveAlias(string name) -> string\n    {\n        var seen, current;\n\n        let seen    = [];\n        let current = name;\n\n        while (array_key_exists(current, this->aliases)) {\n            if (array_key_exists(current, seen)) {\n                throw new CircularAliasFound(name);\n            }\n\n            let seen[current] = true;\n            let current       = this->aliases[current];\n        }\n\n        return current;\n    }\n\n    /**\n     * Resolve a paramater\n     *\n     * @param string $name\n     *\n     * @return mixed\n     */\n    private function resolveParameter(string name) -> mixed\n    {","sourceCodeStart":747,"sourceCodeEnd":783,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Container/Container.zep#L747-L783","documentation":"resolveAlias() follows the alias map until it reaches a key that is not itself an alias, tracking visited keys; CircularAliasFound is thrown at resolution time when a key repeats. setAlias() normally prevents cycles at registration, so encountering this during get()/has() means the alias map was modified outside that guard or the container state got corrupted.","triggerScenarios":"A custom Container subclass or serialized/cached container writing to the alias array directly; a cache/serialization round-trip that restored inconsistent alias state; runtime alias registration racing in long-running workers.","commonSituations":"Container snapshots cached between requests; plugins registering aliases at runtime; state restored from sleep/wakeup or a cache backend.","solutions":["Rebuild the alias map from scratch: clear aliases and re-register each one via setAlias() so cycle detection runs again","Audit any code that writes to the alias map directly and route all changes through setAlias()","Invalidate any cached/serialized container after alias changes instead of reusing stale state","Catch CircularAliasFound during boot and fail fast, logging the alias chain for diagnosis"],"exampleFix":"// before\n$container->aliases = ['db' => 'database', 'database' => 'db']; // bypasses guard\n$container->get('db'); // CircularAliasFound\n\n// after\n$container->set('db', Connection::class);\n$container->setAlias('db', 'database');","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"use Phalcon\\Container\\Exceptions\\CircularAliasFound;\n\ntry {\n    $service = $container->get('db');\n} catch (CircularAliasFound $e) {\n    // alias map is inconsistent: rebuild aliases via setAlias() from a known-good table\n    throw new LogicException('Corrupt alias map, rebuild container aliases', 0, $e);\n}","preventionTips":["Never write to the alias map directly; always go through setAlias()","Do not cache/serialize containers across alias changes — invalidate instead","Register aliases once at boot from a declarative config so the guard in setAlias() always runs"],"tags":["di-container","alias","circular-reference","phalcon"],"backgroundTag":"circular-reference-detected","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}