"Cannot autowire service..." when autowiring to new module's service that is yet to be installed

Created on 24 February 2025, 12 days ago

Problem/Motivation

A module that has autowired services that depend on a to-be-installed module cannot be deployed automatically.

module1 has a my.service:

services:
  my.service:
    class: Drupal\mymodule\Service\MyService
    autowire: true

The service depends on My2Service

class MyService {

  public function __construct(protected My2Service $my2Service) {}
}

module2 has a my2.service

services:
  my2.service:
    class: Drupal\my2module\Service\My2Service
    autowire: true
  Drupal\my2module\Service\My2Service: '@my2.service'

Steps to reproduce

1. Enable module 1 without autowiring changes
2. Make autowiring changes that depend on new module 2
3. Add update hook to enable module 2
4. Run `drush updb`

Error:

In DefinitionErrorExceptionPass.php line 51:                                     
                                                                                   
Cannot autowire service "my.service": argument "$my2Service" of method "Drupal\mymodule\Service\MyService::__construct()" has type "\Drupal\my2module\Service\My2Service" but this class couldn't be loaded. Either it was not found or it is missing a parent class or a trait.  

This is manually fixable by using drush to enable the missing module. Using an update hook to enable the module does not work, as it errors out before running the hook.

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Active

Version

10.3 ✨

Component

bootstrap system

Created by

πŸ‡ΊπŸ‡ΈUnited States djdevin Philadelphia

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @djdevin
  • Module classes are not in the container or autoloaded if the module is not installed so I think this is to be expected? Does module2 depend on module1 in its info.yml file?

  • πŸ‡ΊπŸ‡ΈUnited States djdevin Philadelphia

    Yes, the dependencies are setup correctly (mod1 depends on mod2).

    On a fresh install it works fine, issue seems to be introducing autowiring during an update - seems to be no way I can get the module enabled in time before that error throws.

  • You may have to write a service factory class in module1 to dynamically load the new dependency if available or else do something else. I don't know whether this can be "fixed" as if it is a bug.

  • πŸ‡³πŸ‡ΏNew Zealand quietone

    Changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to the Core change policies β†’ .

  • πŸ‡¬πŸ‡§United Kingdom catch

    There's some amount of support for optional dependencies in the container, see https://symfony.com/doc/current/service_container/optional_dependencies....

    I'm not sure exactly if/how this is supported with autowiring, but you might be able to do that, then make the service non-optional once you can ensure that every site has updated to the version with the new dependency.

Production build 0.71.5 2024