{"record":{"id":"0dad28b6f1385af3","repo":"phalcon/cphalcon","slug":"a-dependency-injection-container-is-required-to-ac-0dad28","errorCode":null,"errorMessage":"A dependency injection container is required to access the 'url' service","messagePattern":"A dependency injection container is required to access the 'url' service","errorType":"exception","errorClass":"Phalcon\\Http\\Response\\Exceptions\\UrlServiceUnavailable","httpStatus":null,"severity":"error","filePath":"phalcon/Http/Response.zep","lineNumber":126,"sourceCode":"    public function getCookies() -> <CookiesInterface>\n    {\n        return this->cookies;\n    }\n\n    /**\n     * Returns the internal dependency injector\n     */\n    public function getDI() -> <DiInterface>\n    {\n        var container;\n\n        let container = <DiInterface> this->container;\n\n        if container === null {\n            let container = Di::getDefault();\n\n            if container === null {\n                throw new UrlServiceUnavailable();\n            }\n\n            let this->container = container;\n        }\n\n        return container;\n    }\n\n    /**\n     * Returns headers set by the user\n     */\n    public function getHeaders() -> <HeadersInterface>\n    {\n        return this->headers;\n    }\n\n    /**\n     * Returns the reason phrase","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Http/Response.zep#L108-L144","documentation":"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.","triggerScenarios":"$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.","commonSituations":"Tests constructing Response manually; workers that build and send responses outside the MVC lifecycle; apps that clear Di::getDefault() during shutdown or handoff.","solutions":["Inject the container: $response->setDI($di); before calling redirect() or other DI-dependent methods","Ensure a default container exists at bootstrap: $di = new FactoryDefault(); Di::setDefault($di);","In tests, fetch the shared 'response' service from a booted container instead of new Response()"],"exampleFix":"// before\n$response = new \\Phalcon\\Http\\Response();\n$response->redirect('/login')->send(); // throws: no DI for 'url'\n\n// after\n$di = new \\Phalcon\\Di\\FactoryDefault();\n$response = new \\Phalcon\\Http\\Response();\n$response->setDI($di);\n$response->redirect('/login')->send();","handlingStrategy":"validation","validationCode":"use Phalcon\\Di\\Di;\n\nif (null === Di::getDefault()) {\n    Di::setDefault($di); // or explicitly: $response->setDI($di);\n}\n$response->redirect('/login');","typeGuard":null,"tryCatchPattern":"try { $response->redirect('/login'); } catch (\\Phalcon\\Http\\Response\\Exceptions\\UrlServiceUnavailable $e) { // wiring bug: inject container and retry once\n    $response->setDI($GLOBALS['di']);\n    $response->redirect('/login');\n}","preventionTips":["Always call setDI() on manually created Response objects","Keep a default DI container alive for the entire request lifecycle","In tests, boot FactoryDefault in setUp() before touching Response"],"tags":["php","phalcon","response","dependency-injection","redirect"],"backgroundTag":"missing-di-container","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}