phalcon/cphalcon · error · Phalcon\Http\Response\Exceptions\UrlServiceUnavailable

A dependency injection container is required to access the '

Error message

A dependency injection container is required to access the 'url' service

What it means

Response::getDI() returns the injected container or falls back to Di::getDefault(); when both are null it throws UrlServiceUnavailable. The message names the 'url' service because getDI() is typically reached from helpers that need it - e.g. redirect() resolves the shared 'url' service to build the Location header.

Source

Thrown at phalcon/Http/Response.zep:126

    public function getCookies() -> <CookiesInterface>
    {
        return this->cookies;
    }

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

        let container = <DiInterface> this->container;

        if container === null {
            let container = Di::getDefault();

            if container === null {
                throw new UrlServiceUnavailable();
            }

            let this->container = container;
        }

        return container;
    }

    /**
     * Returns headers set by the user
     */
    public function getHeaders() -> <HeadersInterface>
    {
        return this->headers;
    }

    /**
     * Returns the reason phrase

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Inject the container: $response->setDI($di); before calling redirect() or other DI-dependent methods
  2. Ensure a default container exists at bootstrap: $di = new FactoryDefault(); Di::setDefault($di);
  3. In tests, fetch the shared 'response' service from a booted container instead of new Response()

Example fix

// before
$response = new \Phalcon\Http\Response();
$response->redirect('/login')->send(); // throws: no DI for 'url'

// after
$di = new \Phalcon\Di\FactoryDefault();
$response = new \Phalcon\Http\Response();
$response->setDI($di);
$response->redirect('/login')->send();
Defensive patterns

Strategy: validation

Validate before calling

use Phalcon\Di\Di;

if (null === Di::getDefault()) {
    Di::setDefault($di); // or explicitly: $response->setDI($di);
}
$response->redirect('/login');

Try / catch

try { $response->redirect('/login'); } catch (\Phalcon\Http\Response\Exceptions\UrlServiceUnavailable $e) { // wiring bug: inject container and retry once
    $response->setDI($GLOBALS['di']);
    $response->redirect('/login');
}

Prevention

When it happens

Trigger: $response = new Response(); $response->redirect('/login'); with no setDI() and no default DI - CLI workers, unit tests, or after the default DI was reset before the response was sent.

Common situations: Tests constructing Response manually; workers that build and send responses outside the MVC lifecycle; apps that clear Di::getDefault() during shutdown or handoff.

Related errors


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