phalcon/cphalcon · critical · Phalcon\Cli\Console\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\Cli\Console (the CLI task runner) resolves all of its moving parts - router, dispatcher, modules, services - from a dependency injection container inherited from AbstractApplication. handle() refuses to run without one and throws ContainerRequired immediately, before the boot event fires, because nothing (routing, dispatching, module service registration) can work container-less.

Source

Thrown at phalcon/Cli/Console.zep:55

     */
    protected var arguments = [];
    /**
     * @phpstan-var cli_options
     */
    protected array options = [];

    /**
     * Handle the whole command-line tasks
     *
     * @phpstan-param cli_parameters|null $arguments
     */
    public function handle(array arguments = null)
    {
        var className, dispatcher, module, moduleName,
            moduleObject, path, router, task;

        if this->container === null {
            throw new ContainerRequired();
        }

        /**
         * Call boot event, this allows the developer to perform initialization
         * actions
         */
        if this->eventsManager !== null {
            if this->eventsManager->fire("console:boot", this) === false {
                return false;
            }
        }

        let router = <Router> this->container->getShared("router");

        if empty arguments && this->arguments {
            router->handle(this->arguments);
        } else {
            router->handle(arguments);

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Set the container before handling: $console->setDI($di) (or rely on the default Di::getDefault() if already initialized in your bootstrap)
  2. Ensure the DI provides the services CLI dispatch needs: 'router' and 'dispatcher' (CLI-flavored) plus anything your tasks resolve
  3. In tests, construct and set a Di with the minimal CLI services instead of running handle() bare

Example fix

// before
$console = new \Phalcon\Cli\Console();
$console->handle(['task' => 'main', 'action' => 'main']);

// after
$di = new \Phalcon\Di\Di();
$di->set('router', new \Phalcon\Cli\Router(), true);
$console = new \Phalcon\Cli\Console();
$console->setDI($di);
$console->handle(['task' => 'main', 'action' => 'main']);
Defensive patterns

Strategy: validation

Validate before calling

if ($console->getDI() === null) {
    $di = new \Phalcon\Di\Di();
    $di->set('router', new \Phalcon\Cli\Router(), true);
    $di->set('dispatcher', new \Phalcon\Cli\Dispatcher(), true);
    $console->setDI($di);
}
$console->handle($arguments);

Try / catch

try {
    $console->handle($argvParams);
} catch (\Phalcon\Cli\Console\Exceptions\ContainerRequired $e) {
    // programming error in bootstrap: setDI() was skipped; fix and re-run, do not retry in a loop
}

Prevention

When it happens

Trigger: $console = new Console(); $console->handle(['task' => 'main']); without ever calling $console->setDI($di); using a console built in a bootstrap that conditionally skips DI setup (e.g. only sets DI for HTTP SAPI); unit tests constructing Console directly.

Common situations: Minimal CLI entry scripts copied from docs that omit the setDI line; shared bootstrap that wires DI only when $_SERVER['REQUEST_URI'] is present; refactoring a web app into CLI tasks and forgetting the container; test harnesses instantiating Console without the DI fixture.

Related errors


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