{"record":{"id":"773eaad169dff640","repo":"phalcon/cphalcon","slug":"a-dependency-injection-container-is-required-to-ac-773eaa","errorCode":null,"errorMessage":"A dependency injection container is required to access application services","messagePattern":"A dependency injection container is required to access application services","errorType":"exception","errorClass":"Phalcon\\Mvc\\View\\Exceptions\\ViewServicesUnavailable","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/View.zep","lineNumber":1308,"sourceCode":"        let engines = this->engines;\n\n        /**\n         * If the engines aren't initialized 'engines' is false\n         */\n        if engines === false {\n            let di = <DiInterface> this->container;\n\n            let engines = [];\n            let registeredEngines = this->registeredEngines;\n\n            if empty registeredEngines {\n                /**\n                 * We use Phalcon\\Mvc\\View\\Engine\\Php as default\n                 */\n                let engines[\".phtml\"] = new PhpEngine(this, di);\n            } else {\n                if typeof di != \"object\" {\n                    throw new ViewServicesUnavailable();\n                }\n\n                for extension, engineService in registeredEngines {\n                    if typeof engineService == \"object\" {\n                        /**\n                         * Engine can be a closure\n                         */\n                        if engineService instanceof Closure {\n                            let engineService = Closure::bind(\n                                engineService,\n                                di\n                            );\n\n                            let engines[extension] = call_user_func(\n                                engineService,\n                                this\n                            );\n                        } else {","sourceCodeStart":1290,"sourceCodeEnd":1326,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/View.zep#L1290-L1326","documentation":"View::registerEngines() records engine definitions but they are lazily resolved on first render, when a DI container is needed to instantiate engines from service names (phalcon/Mvc/View.zep:1308). If registered engines exist and the attached container is not an object, ViewServicesUnavailable is thrown — the default single-engine path (plain PhpEngine) needs no container, so this only fires once you register custom engines.","triggerScenarios":"$view = new View(); $view->registerEngines(['.volt' => ...]); $view->render(...) without ever calling setDI(); rendering a view template from a queue worker or CLI script where the DI was not bootstrapped; unit tests constructing View directly.","commonSituations":"CLI email-rendering workers that reuse View but skip full app bootstrap; test harnesses that new up View; refactoring a controller-rendered template into a background job without carrying the container.","solutions":["Attach the container once at setup: $view->setDI($di) before any render","Reuse the app's DI in workers/tests instead of a bare new View()","If you only need plain PHP templates, remove registerEngines() calls so the PhpEngine default (no container needed) is used"],"exampleFix":"// before\n$view = new \\Phalcon\\Mvc\\View();\n$view->setViewsDir($dir);\n$view->registerEngines(['.volt' => 'voltService']);\necho $view->render('mails/welcome'); // no DI -> ViewServicesUnavailable\n\n// after\n$view = new \\Phalcon\\Mvc\\View();\n$view->setViewsDir($dir);\n$view->setDI($app->getDI());\n$view->registerEngines(['.volt' => 'voltService']);\necho $view->render('mails/welcome');","handlingStrategy":"validation","validationCode":"if ($view->getRegisteredEngines() && $view->getDI() === null) {\n    throw new \\RuntimeException('Custom view engines require a DI container; call View::setDI()');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair registerEngines() with setDI() in the same setup block","Reuse the application DI in CLI workers and tests","Skip registerEngines() if only .phtml templates are rendered"],"tags":["phalcon","view","di","engines","lazy-initialization"],"backgroundTag":"missing-di-container","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}