phalcon/cphalcon · error · TypeError

The parameter must be an instance of Collection or DiInterfa

Error message

The parameter must be an instance of Collection or DiInterface

What it means

Phalcon\Support\AbstractLocator (base for service locators such as access locators) stores a container to resolve services from; its constructor accepts only Phalcon\Contracts\Container\Service\Collection (new Container) or Phalcon\Di\DiInterface (legacy Di) and throws \TypeError for anything else (phalcon/Support/AbstractLocator.zep:48). The parameter is untyped on purpose to allow both, which is why the check is manual.

Source

Thrown at phalcon/Support/AbstractLocator.zep:48

    /**
     * @var Collection|DiInterface
     */
    protected container;

    /**
     * @phpstan-var array<string, class-string<T>>
     */
    protected array services = [];

    /**
     * @phpstan-param array<string, class-string<T>> $services
     */
    public function __construct(
        var container,
        array services = []
    ) {
        if (!(container instanceof Collection) && !(container instanceof DiInterface)) {
            throw new \TypeError("The parameter must be an instance of Collection or DiInterface");
        }

        var definition, name;

        let this->container = container;
        let this->services  = this->getServices();

        for name, definition in services {
            this->register(name, definition);
        }
    }

    /**
     * Returns the full registered service map (defaults plus any added via
     * register()).
     *
     * @return array<string, class-string<T>>
     */

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Pass a valid container: Phalcon\Di\Di::getDefault() (or your app's DiInterface) or a Phalcon\Contracts\Container\Service\Collection instance.
  2. Construct the locator lazily (as a DI service/factory) so the container is guaranteed to exist at build time.
  3. Add an instanceof check before instantiation when the container arrives from variable sources.

Example fix

// before
$locator = new AccessLocator(null); // TypeError

// after
$locator = new AccessLocator(Phalcon\Di\Di::getDefault());
Defensive patterns

Strategy: type-guard

Type guard

use Phalcon\Contracts\Container\Service\Collection;
use Phalcon\Di\DiInterface;

/** @param mixed $container @return Collection|DiInterface */
function normalizeLocatorContainer(mixed $container): Collection|DiInterface
{
    if ($container instanceof Collection || $container instanceof DiInterface) {
        return $container;
    }
    return Phalcon\Di\Di::getDefault();
}

Prevention

When it happens

Trigger: new SomeLocator(null), new SomeLocator(new stdClass()), or passing a foreign container (e.g. a PSR-11 implementation) that implements neither interface.

Common situations: Migrating between the legacy Di and the new Container and passing the wrong object; constructing the locator before the DI exists so null slips in; assuming any container-interop object works.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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