Circular dependency error with Drupal 11.3 hook system: CurrentUserDataProvider triggers hook_entity_type_build during container construction
Related to https://git.drupalcode.org/project/eca/-/work_items/3567623 , a new circular dependency issue.
## Issue summary:
After upgrading to Drupal 11.3, any drush command (or full page request when the container cache is cold) fails with:
Circular reference detected for service "Drupal\modeler_api\Hook\EntityHooks", path: "scheduler.manager -> date.formatter -> Drupal\modeler_api\Hook\EntityHooks -> modeler_api.service -> router.no_access_checks -> method_filter -> Drupal\mailer_override\OverrideManagerInterface -> eca.service.token -> eca.token_data.current_user"
### Root cause:
Drupal 11.3 changed how #[Hook] attribute classes work: they are now registered as eagerly-instantiated, autowired container services via HookCollectorPass. Previously, hook implementations were invoked procedurally at runtime and never became DI container services.
This exposed a latent problem in CurrentUserDataProvider::__construct(), which immediately calls $entity_type_manager->getStorage('user'). That call triggers EntityTypeManager::getDefinitions(), which invokes hook_entity_type_build via the module handler. With 11.3's new hook system, invoking hook_entity_type_build requires instantiating EntityHooks services — but those services may already be mid-construction earlier in the dependency chain, creating the circular reference.
The cycle closes like this:
- EntityHooks (being built)
- → modeler_api.service → router.no_access_checks → method_filter → mailer_override\OverrideManagerInterface
- → eca.service.token (collects eca.token_data.current_user)
- → CurrentUserDataProvider::__construct() calls getStorage('user')
- → triggers hook_entity_type_build → requests EntityHooks
- → already being built → circular
### Fix:
Defer the getStorage('user') call from the constructor to first use:
```
// Before
public function __construct(AccountProxyInterface $current_user, EntityTypeManagerInterface $entity_type_manager) {
$this->currentUser = $current_user;
$this->userStorage = $entity_type_manager->getStorage('user');
}
// After
public function __construct(AccountProxyInterface $current_user, EntityTypeManagerInterface $entity_type_manager) {
$this->currentUser = $current_user;
$this->entityTypeManager = $entity_type_manager;
}
public function getData(string $key): ?EntityInterface {
if ($key === 'user' || $key === 'current_user') {
return $this->entityTypeManager->getStorage('user')->load($this->currentUser->id());
}
return NULL;
}
```
### Steps to reproduce:
1. Install Drupal 11.3.x
2. Install ECA 3.1.2, modeler_api, symfony_mailer with mailer_override, scheduler
3. Clear the container cache (or cold-boot)
4. Run any drush command
(Issue summary and diagnosis assisted by Claude Sonnet)
issue