phalcon/cphalcon · error · Phalcon\Mvc\Model\Exceptions\InvalidConnectionService

Invalid injected connection service

Error message

Invalid injected connection service

What it means

Thrown by Manager::getConnection() after the DI container resolved the model's connection service to something that is not an object. The service name comes from the model's getConnectionService() (default 'db') or from the manager's per-model connectionServices overrides; container->getShared(service) must return an object (a Phalcon\Db\Adapter\AdapterInterface). When the registered service returns null, a string, an array or any scalar, the connection lookup is aborted with this exception.

Source

Thrown at phalcon/Mvc/Model/Manager.zep:2491

        array connectionServices
    ) -> <AdapterInterface> {
        var container, service, connection;

        let service = this->getConnectionService(model, connectionServices);

        let container = <DiInterface> this->container;

        if unlikely typeof container != "object" {
            throw new ManagerOrmServicesUnavailable();
        }

        /**
         * Request the connection service from the DI
         */
        let connection = <AdapterInterface> container->getShared(service);

        if unlikely typeof connection != "object" {
            throw new InvalidConnectionService();
        }

        return connection;
    }

    /**
     * @param string $collection
     * @param string $modelName
     * @param string $modelRelation
     *
     * @return bool
     */
    private function checkHasRelationship(
        string collection,
         string modelName,
         string modelRelation
    ) -> bool {
        var entityName;

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Inspect $di->getService($model->getConnectionService()) and change its definition so every path returns a Phalcon\Db\Adapter\AdapterInterface instance.
  2. Verify the name: call $model->getConnectionService() (or getReadConnectionService()/getWriteConnectionService()) and confirm a service with exactly that name is registered.
  3. If a factory closure returns conditionally, make sure no branch returns null or an array.
  4. For multi-database apps, register every connection name any model references.

Example fix

// before
$di->set('db', function () {
    return $this->getConfig()->database->toArray(); // array, not an adapter
});
$manager->getConnection($invoice); // InvalidConnectionService

// after
$di->set('db', function () {
    $cfg = $this->getConfig()->database;
    return new Phalcon\Db\Adapter\Pdo\Mysql([
        'host'     => $cfg->host,
        'username' => $cfg->username,
        'password' => $cfg->password,
        'dbname'   => $cfg->dbname,
    ]);
});
Defensive patterns

Strategy: type-guard

Validate before calling

$service = $model->getConnectionService();
if (!$di->has($service) || !is_object($di->getShared($service))) {
    throw new RuntimeException('Connection service "' . $service . '" does not resolve to an object');
}

Type guard

use Phalcon\Db\Adapter\AdapterInterface;
use Phalcon\Di\DiInterface;

function connectionServiceIsAdapter(DiInterface $di, string $service): bool
{
    return $di->getShared($service) instanceof AdapterInterface;
}

Try / catch

use Phalcon\Mvc\Model\Exceptions\InvalidConnectionService;

try {
    $connection = $manager->getConnection($model);
} catch (InvalidConnectionService $e) {
    // fail fast with actionable context; do not retry a misconfigured service
    throw new RuntimeException(
        'Service "' . $model->getConnectionService() . '" must return an AdapterInterface',
        0,
        $e
    );
}

Prevention

When it happens

Trigger: A DI service registered under the model's connection service name that returns a non-object: a closure returning a config array, a service defined as raw array settings, a factory whose error path returns null, or $model->setConnectionService('databse') (typo) resolving a service that exists but is not a connection object.

Common situations: Registering 'db' as an array of connection parameters instead of a factory returning an Adapter; multi-database setups where one of the named connections was never registered; typos in setConnectionService()/setReadConnectionService()/setWriteConnectionService(); test doubles for the DI that return strings from getShared().

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/47d8e71370282fb8. Report an issue: GitHub.