phalcon/cphalcon · error · Phalcon\Container\Exceptions\CircularAliasFound
Circular alias detected: '{alias}'
Error message
Circular alias detected: '{alias}' What it means
setAlias(name, alias) walks the existing alias chain starting from the target to verify the new alias cannot loop back onto itself; CircularAliasFound is thrown when following the chain returns to the new alias. Cycles are rejected because alias resolution would never terminate.
Source
Thrown at phalcon/Container/Container.zep:665
/**
* Detect circular aliases
*
* @param string $alias
* @param string $target
*
* @return void
* @throws CircularAliasFound
*/
private function detectCircularAlias(string alias, string target) -> void
{
var current, seen;
let current = target;
let seen = [];
while (true) {
if (current === alias) {
throw new CircularAliasFound(alias);
}
if (array_key_exists(current, seen)) {
break;
}
if (!array_key_exists(current, this->aliases)) {
break;
}
let seen[current] = true;
let current = this->aliases[current];
}
}
/**
* Locate a processor
*View on GitHub (pinned to b7419de9cd)
Solutions
- Keep aliases one-directional — every alias chain must terminate at a real registered service name
- Remove the old reverse mapping before adding a new alias in the opposite direction (rebuild the alias set cleanly)
- Sketch or assert the chain before registering; check with hasAlias() to catch duplicates
- Never self-alias: setAlias('x', 'x') is always a cycle
Example fix
// before
$c->setAlias('db', 'database');
$c->setAlias('database', 'db'); // CircularAliasFound
// after
$c->set('db', Pdo\Connection::class);
$c->setAlias('db', 'database'); // database -> db (terminates) Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate that adding alias -> target keeps the graph acyclic
function aliasWouldCycle(array $aliases, string $alias, string $target): bool
{
$current = $target;
while (isset($aliases[$current])) {
if ($current === $alias) {
return true;
}
$current = $aliases[$current];
}
return false;
}
if (!aliasWouldCycle($aliasMap, 'database', 'db')) {
$container->setAlias('db', 'database');
} Try / catch
use Phalcon\Container\Exceptions\CircularAliasFound;
try {
$container->setAlias('database', 'db');
} catch (CircularAliasFound $e) {
// log and abort bootstrap: alias chain loops, fix the mapping table
} Prevention
- Maintain aliases as a flat declarative map (alias => final service) validated at boot, never bidirectional
- Every alias chain must end at a real service name; draw the chain before adding links
- Never self-alias or add reverse aliases after refactors
When it happens
Trigger: setAlias('db', 'database') followed by setAlias('database', 'db') (two-way alias); longer cycles a->b->c->a introduced one link at a time; a self-alias setAlias('db', 'db').
Common situations: Two modules each registering a friendly name that points at the other; copy-pasted alias setup where direction was flipped; refactors that add a reverse alias without removing the old one.
Related errors
- Circular alias detected: '{name}'
- Service '{name}' not found
- Instance '{name}' not found
- Parameter '{name}' not found
- Service '{name}' not registered
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/6fd4322cb3d0bd48.
Report an issue: GitHub.