yiisoft/yii2 · error · Exception

Could not load required service: {name}

Error message

Could not load required service: {name}

What it means

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.

Source

Thrown at framework/base/Controller.php:595

     */
    final protected function bindInjectedParams(\ReflectionNamedType $type, $name, &$args, &$requestedParams)
    {
        // Since it is not a builtin type it must be DI injection.
        $typeName = $type->getName();
        if (($component = $this->module->get($name, false)) instanceof $typeName) {
            $args[] = $component;
            $requestedParams[$name] = 'Component: ' . get_class($component) . " \$$name";
        } elseif ($this->module->has($typeName) && ($service = $this->module->get($typeName)) instanceof $typeName) {
            $args[] = $service;
            $requestedParams[$name] = 'Module ' . get_class($this->module) . " DI: $typeName \$$name";
        } elseif (\Yii::$container->has($typeName) && ($service = \Yii::$container->get($typeName)) instanceof $typeName) {
            $args[] = $service;
            $requestedParams[$name] = "Container DI: $typeName \$$name";
        } elseif ($type->allowsNull()) {
            $args[] = null;
            $requestedParams[$name] = "Unavailable service: $name";
        } else {
            throw new Exception('Could not load required service: ' . $name);
        }
    }
}

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Register the binding in the application config: 'container' => ['singletons' => [InvoiceRepositoryInterface::class => InvoiceRepository::class]] (or Yii::$container->setSingleton(...))
  2. If the service is optional, make the parameter nullable (InvoiceRepository $repo = null) - Yii then injects null instead of throwing
  3. If it is app-wide, configure it under 'components' so the application-component branch resolves it
  4. Verify the type-hint names a real, instantiable class

Example fix

// before
public function actionPdf(InvoiceRepositoryInterface $repo) { /* ... */ }
// Exception: Could not load required service: repo

// after (config/web.php)
'container' => [
    'singletons' => [
        \app\repositories\InvoiceRepositoryInterface::class => \app\repositories\InvoiceRepository::class,
    ],
],
Defensive patterns

Strategy: validation

Validate before calling

use app\repositories\InvoiceRepositoryInterface;
if (!\Yii::$container->has(InvoiceRepositoryInterface::class)) {
    \Yii::$container->setSingleton(InvoiceRepositoryInterface::class, InvoiceRepository::class);
}
// now the action's type-hinted parameter can resolve

Try / catch

try {
    Yii::$app->runAction($route);
} catch (\yii\base\Exception $e) {
    if (strpos($e->getMessage(), 'Could not load required service') === 0) {
        // a required DI binding is missing: register it and retry once
        \Yii::$container->setSingleton($missingInterface, $concrete);
        Yii::$app->runAction($route);
    }
    throw $e;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/b04b9b748d0d4bca. Report an issue: GitHub.