phalcon/cphalcon · error · Phalcon\DataMapper\Pdo\Exception\ConnectionNotFound
Connection not found: {type}:{requested}
Error message
Connection not found: {type}:{requested} What it means
ConnectionLocator stores named connection factories per role (read, write, plus a 'default'). When the requested name is absent from that role's collection it throws ConnectionNotFound with 'type:name'. An empty requested name selects a random entry — but only from a non-empty collection, so a role with no configured factories also fails.
Source
Thrown at phalcon/DataMapper/Pdo/ConnectionLocator.zep:212
/**
* No collection returns the master
*/
if empty collection {
return this->getMaster();
}
/**
* If the requested name is empty, get a random connection
*/
if "" === requested {
let requested = array_rand(collection);
}
/**
* If the connection name does not exist, send an exception back
*/
if !isset collection[requested] {
throw new ConnectionNotFound(
"Connection not found: " . type . ":" . requested
);
}
/**
* Check if the connection has been resolved already, if yes return
* it, otherwise resolve it. The keys in the `resolved` array are
* formatted as "type-name"
*/
let instanceName = type . "-" . requested;
if !isset instances[instanceName] {
let instances[instanceName] = call_user_func(collection[requested]),
this->instances = instances;
}
return this->applyEventsManager(instances[instanceName]);
}View on GitHub (pinned to b7419de9cd)
Solutions
- Register the name before use: $locator->setRead('slave2', $factory)
- Validate requested names against a known-names list from config before calling getRead()/getWrite()
- Ensure each role has at least one entry (typically 'default') so empty-string random selection has something to pick
- Centralize connection names in one config array/constants to prevent drift between config and code
Example fix
// before
$conn = $locator->getRead('slave2'); // ConnectionNotFound: read:slave2
// after
$locator->setRead('slave2', function () use ($dsn2) {
return new \Phalcon\DataMapper\Pdo\Connection($dsn2, 'user', 'pass');
});
$conn = $locator->getRead('slave2'); Defensive patterns
Strategy: validation
Validate before calling
// Validate against the configured replica names before lookup
$readReplicas = array_keys($config->get('database.replicas'));
if ($name !== '' && !in_array($name, $readReplicas, true)) {
throw new InvalidArgumentException(
"Unknown read connection '{$name}'; configured: " . implode(', ', $readReplicas)
);
}
$conn = $locator->getRead($name); Try / catch
use Phalcon\DataMapper\Pdo\Exception\ConnectionNotFound;
try {
$conn = $locator->getRead($name);
} catch (ConnectionNotFound $e) {
$conn = $locator->getRead('default'); // fall back to the default read connection
} Prevention
- Always configure a 'default' factory for each role so fallback exists
- Derive requested connection names from the same config that registers them — never hardcode separately
- Guard dynamic names (shards, replicas) with a known-names check before getRead()/getWrite()
When it happens
Trigger: $locator->getRead('slave2') when only 'slave1' or nothing was registered with setRead(); a typo or config/code naming mismatch (slave vs replica); getWrite() when only read factories were configured; requesting 'default' after the default factory was never set.
Common situations: Replica config keys not matching the names code requests; environments without replicas where no fallback default was registered; dynamically computed shard/replica names at runtime.
Related errors
- Driver not supported [{driver}]
- Class '{className}' does not have a method '{name}'
- Cannot disconnect a Decorated connection instance
- Operation cancelled by a listener of '{eventName}'
- Invalid bind parameter (1)
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/6cf2847237bf78d5.
Report an issue: GitHub.