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
- Pass the container explicitly: new Manager($di) where $di has the 'db' service registered
- Call Di::setDefault($di) before any Manager instantiation if you rely on the default-container fallback
- Register the manager as a DI service ('transactionManager' => Manager::class) so it is only constructed after the container is live
- 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
- Always pass the container explicitly instead of relying on Di::getDefault()
- Register 'transactionManager' as a DI service so wiring is guaranteed at resolution time
- In tests, build a minimal container with a 'db' double before any Manager creation
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
- A dependency injection container is required to access inter
- Invalid injected connection service
- The dependency injector is invalid
- Transaction aborted
- A dependency injection container is required to access the '
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/edefcbbadbc18e2c.
Report an issue: GitHub.