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

A dependency injection container is required to access the s

Error message

A dependency injection container is required to access the services related to the ORM

What it means

Phalcon\Mvc\Model\Transaction\Manager needs the DI container to resolve the 'db' service when creating transactions. Its constructor falls back to Di::getDefault(); if no container was passed and no default container has been set (Di::setDefault never called), it throws ManagerOrmServicesUnavailable immediately at construction time.

Source

Thrown at phalcon/Mvc/Model/Transaction/Manager.zep:111

     * @var array
     */
    protected transactions = [];

    /**
     * Phalcon\Mvc\Model\Transaction\Manager constructor
     *
     * @param DiInterface|null container
     */
    public function __construct(<DiInterface> container = null)
    {
        if !container {
            let container = Di::getDefault();
        }

        let this->container = container;

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

    /**
     * Remove all the transactions from the manager
     */
    public function collectTransactions() -> void
    {
        var transactions;

        let transactions = this->transactions;

        for _ in transactions {
            let this->number--;
        }

        let this->transactions = [];
    }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Pass the container explicitly: new Manager($di) where $di has the 'db' service registered
  2. Call Di::setDefault($di) before any Manager instantiation if you rely on the default-container fallback
  3. Register the manager as a DI service ('transactionManager' => Manager::class) so it is only constructed after the container is live
  4. In tests, set up a minimal container with a 'db' service (or double) before creating the Manager

Example fix

// before
$txManager = new \Phalcon\Mvc\Model\Transaction\Manager(); // no default DI -> throws

// after
$di = new \Phalcon\Di\Di();
$di->set('db', fn() => new \Phalcon\Db\Adapter\Pdo\Mysql($config->db->toArray()));
$txManager = new \Phalcon\Mvc\Model\Transaction\Manager($di);
// or earlier: \Phalcon\Di\Di::setDefault($di);
Defensive patterns

Strategy: validation

Validate before calling

// Before constructing the manager standalone
use Phalcon\Di\Di;

$di = Di::getDefault();
if ($di === null) {
    throw new RuntimeException('Set up the DI container (with a "db" service) before using transactions');
}
$txManager = new \Phalcon\Mvc\Model\Transaction\Manager($di);

Try / catch

try {
    $txManager = new \Phalcon\Mvc\Model\Transaction\Manager($di);
} catch (\Phalcon\Mvc\Model\Exceptions\ManagerOrmServicesUnavailable $e) {
    // bootstrap the container and retry construction once
    $di = bootstrapDi();
    $txManager = new \Phalcon\Mvc\Model\Transaction\Manager($di);
}

Prevention

When it happens

Trigger: Executing new Manager() in a fresh CLI script, unit test, or worker before any DI container exists; constructing the manager statically at bootstrap before the application registers its services; instantiating it in a context where the default container was cleared (Di::reset()).

Common situations: PHPUnit tests that build a Manager without the application bootstrap; long-running queue workers with their own minimal bootstrapping; library code that news up the manager instead of resolving 'transactionManager' from DI; calling Di::reset() between requests in tests.

Related errors


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