Active
Project:
Drupal core
Version:
main
Component:
base system
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
24 Feb 2025 at 17:33 UTC
Updated:
3 Sep 2025 at 03:30 UTC
Jump to comment: Most recent
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'
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.
Comments
Comment #2
cilefen commentedModule 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?
Comment #3
djdevinYes, 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.
Comment #4
cilefen commentedYou 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.
Comment #5
quietone commentedChanges are made on on 11.x (our main development branch) first, and are then back ported as needed according to the Core change policies.
Comment #6
catchThere'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.
Comment #7
nicxvan commentedDoes this belong in the recurrent component?
Comment #8
mstrelan commentedA similar issue occurs when autowiring a service that implements an interface from a module that is not installed. This appears to be a valid thing to do when decorating a service, by using decoration_on_invalid: ignore for when the module is not installed. This works completely fine when manually wiring up the service. It fails during
\Symfony\Component\DependencyInjection\Compiler\AutowireAsDecoratorPass::processas it tries to load the class.