{"record":{"id":"b04b9b748d0d4bca","repo":"yiisoft/yii2","slug":"could-not-load-required-service-name","errorCode":null,"errorMessage":"Could not load required service: {name}","messagePattern":"Could not load required service: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"framework/base/Controller.php","lineNumber":595,"sourceCode":"     */\n    final protected function bindInjectedParams(\\ReflectionNamedType $type, $name, &$args, &$requestedParams)\n    {\n        // Since it is not a builtin type it must be DI injection.\n        $typeName = $type->getName();\n        if (($component = $this->module->get($name, false)) instanceof $typeName) {\n            $args[] = $component;\n            $requestedParams[$name] = 'Component: ' . get_class($component) . \" \\$$name\";\n        } elseif ($this->module->has($typeName) && ($service = $this->module->get($typeName)) instanceof $typeName) {\n            $args[] = $service;\n            $requestedParams[$name] = 'Module ' . get_class($this->module) . \" DI: $typeName \\$$name\";\n        } elseif (\\Yii::$container->has($typeName) && ($service = \\Yii::$container->get($typeName)) instanceof $typeName) {\n            $args[] = $service;\n            $requestedParams[$name] = \"Container DI: $typeName \\$$name\";\n        } elseif ($type->allowsNull()) {\n            $args[] = null;\n            $requestedParams[$name] = \"Unavailable service: $name\";\n        } else {\n            throw new Exception('Could not load required service: ' . $name);\n        }\n    }\n}\n","sourceCodeStart":577,"sourceCodeEnd":599,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/base/Controller.php#L577-L599","documentation":"Since 2.0.16 controllers resolve class-type-hinted action parameters as services, in order: application components ($app->has()/get() with the type name), module DI ($this->module->has()/get()), then Yii::$container; if the parameter is nullable, null is injected as a last resort. When nothing resolves and the parameter is required, parameter binding throws yii\\base\\Exception('Could not load required service: <paramName>') - the name in the message is the PHP parameter name.","triggerScenarios":"public function actionIndex(InvoiceRepositoryInterface $repo) with no container definition for the interface and no app component or module entry of that class name; hinting a concrete class whose own constructor dependencies cannot be autowired recursively; a type-hint naming a nonexistent or misspelled class (nothing can ever resolve it).","commonSituations":"Adopting action DI after reading docs or snippets without adding the 'container' config block; interfaces that each application must map to its own implementation; constructor changes in the service after a dependency update that break autowiring.","solutions":["Register the binding in the application config: 'container' => ['singletons' => [InvoiceRepositoryInterface::class => InvoiceRepository::class]] (or Yii::$container->setSingleton(...))","If the service is optional, make the parameter nullable (InvoiceRepository $repo = null) - Yii then injects null instead of throwing","If it is app-wide, configure it under 'components' so the application-component branch resolves it","Verify the type-hint names a real, instantiable class"],"exampleFix":"// before\npublic function actionPdf(InvoiceRepositoryInterface $repo) { /* ... */ }\n// Exception: Could not load required service: repo\n\n// after (config/web.php)\n'container' => [\n    'singletons' => [\n        \\app\\repositories\\InvoiceRepositoryInterface::class => \\app\\repositories\\InvoiceRepository::class,\n    ],\n],","handlingStrategy":"validation","validationCode":"use app\\repositories\\InvoiceRepositoryInterface;\nif (!\\Yii::$container->has(InvoiceRepositoryInterface::class)) {\n    \\Yii::$container->setSingleton(InvoiceRepositoryInterface::class, InvoiceRepository::class);\n}\n// now the action's type-hinted parameter can resolve","typeGuard":null,"tryCatchPattern":"try {\n    Yii::$app->runAction($route);\n} catch (\\yii\\base\\Exception $e) {\n    if (strpos($e->getMessage(), 'Could not load required service') === 0) {\n        // a required DI binding is missing: register it and retry once\n        \\Yii::$container->setSingleton($missingInterface, $concrete);\n        Yii::$app->runAction($route);\n    }\n    throw $e;\n}","preventionTips":["Define all interface-to-concrete mappings once under the 'container' config key","Keep an integration test that hits every DI-enabled action","Make optional services nullable and required services explicitly registered"],"tags":["dependency-injection","controller","action","service-locator"],"backgroundTag":"unresolved-di-dependency","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}