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
- Pass a valid container: Phalcon\Di\Di::getDefault() (or your app's DiInterface) or a Phalcon\Contracts\Container\Service\Collection instance.
- Construct the locator lazily (as a DI service/factory) so the container is guaranteed to exist at build time.
- 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
- Register locators as DI services so the container argument is resolved by the framework, never hand-built with null.
- Construct locators after the DI is initialized (lazy factories), not during bootstrap constants.
- PSR-11 or custom containers are not accepted — adapt them into a Collection first.
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
- Cannot extend already-resolved service '{name}'
- Argument at position {} must have a type
- Service '{}' is required in parameter on position {}
- Service 'value' is required in parameter on position {}
- Service 'className' is required in parameter on position {}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/89c2e68245c739cb.
Report an issue: GitHub.