phalcon/cphalcon · error · Phalcon\Mvc\Model\MetaData\Exceptions\ContainerRequired

A dependency injection container is required to access inter

Error message

A dependency injection container is required to access internal services

What it means

Phalcon\Mvc\Model\MetaData\MetaData::getDI() returns the DI container attached to the metadata component and throws this exception when none was set. The metadata pipeline needs the container on every cache miss: initializeMetaData() and initializeColumnMap() call getDI() to hand the extraction strategy (Introspection or Annotations) the container it uses to reach the database and the annotations service. So it surfaces not only on direct getDI() calls but on the first metadata computation for any model.

Source

Thrown at phalcon/Mvc/Model/MetaData.zep:348

        if false === isset(this->columnMap[key]) {
            if false === this->initializeColumnMap(model, key) {
                return null;
            }
        }
        return key;
    }

    /**
     * Returns the DependencyInjector container
     */
    public function getDI() -> <DiInterface>
    {
        var container;

        let container = <DiInterface> this->container;

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

        return container;
    }

    /**
     * Returns attributes and their data types
     *
     *```php
     * print_r(
     *     $metaData->getDataTypes(
     *         new Invoices()
     *     )
     * );
     *```
     */
    public function getDataTypes(<ModelInterface> model) -> array
    {

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Call $metaData->setDI($di) right after constructing the adapter.
  2. Prefer resolving the adapter as the shared 'modelsMetadata' service in the DI — Phalcon injects the container automatically.
  3. Ensure a default container exists (Di::setDefault) before any model operation in CLI and worker entry points.

Example fix

// before
$metaData = new Phalcon\Mvc\Model\MetaData\Memory();
$metaData->getAttributes(new Invoices()); // ContainerRequired on first cache miss

// after
$di = Phalcon\Di\Di::getDefault() ?? new Phalcon\Di\FactoryDefault();
$metaData = new Phalcon\Mvc\Model\MetaData\Memory();
$metaData->setDI($di);
$metaData->getAttributes(new Invoices());
Defensive patterns

Strategy: validation

Validate before calling

// Precondition: attach a container before any metadata call
$di = Phalcon\Di\Di::getDefault() ?? new Phalcon\Di\FactoryDefault();
$metaData->setDI($di);

Type guard

function metaDataHasDi(Phalcon\Mvc\Model\MetaData $metaData): bool
{
    try {
        return $metaData->getDI() instanceof \Phalcon\Di\DiInterface;
    } catch (\Phalcon\Mvc\Model\MetaData\Exceptions\ContainerRequired $e) {
        return false;
    }
}

Try / catch

use Phalcon\Mvc\Model\MetaData\Exceptions\ContainerRequired;

try {
    $metaData->getAttributes($model);
} catch (ContainerRequired $e) {
    $metaData->setDI(Phalcon\Di\Di::getDefault());
    $metaData->getAttributes($model);
}

Prevention

When it happens

Trigger: Constructing a MetaData adapter manually (new MetaData\Memory(), new MetaData\Redis([...])) and calling a getter such as getAttributes($model) without setDI(); a custom 'modelsMetadata' service whose factory forgets the container; model usage after the default DI was cleared in a long-running worker.

Common situations: Standalone scripts or PHPUnit harnesses that instantiate metadata adapters directly; refactored bootstrap code that stops resolving modelsMetadata from the DI; workers using Di::getDefault() after it was reset to null.

Related errors


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