ExtraFieldBlockCacheTagInvalidator is tagged cache_tags_invalidator, so it's created together with cache_tags.invalidator. It gets plugin.manager.block in its constructor, and the block manager gets logger.channel.default. So anything that needs cache_tags.invalidator while the default logger channel is being created ends in a ServiceCircularReferenceException.
For us it broke drush on a cold container (11.4.7):
Circular reference detected for service "logger.channel.default", path: "Drupal\Core\Recipe\Command\RecipeCommand -> logger.channel.default -> Drupal\menu_link_content\Hook\MenuLinkContentHooks -> plugin.manager.menu.link -> Drupal\Core\Menu\MenuTreeStorageInterface -> cache_tags.invalidator -> plugin.manager.block"
From the trace: tmgmt_smartling_log_settings replaces the logger channel factory, and its LoggerChannel constructor reads config. On a cold cache the domain config overrider then loads the domain storage, the entity type definitions get built, and hook_entity_type_alter() instantiates MenuLinkContentHooks → plugin.manager.menu.link → menu tree storage → cache_tags.invalidator → layout_builder.extra_fields.invalidator → plugin.manager.block → logger.channel.default again.
Reading config while creating a logger channel isn't great either, but other contrib loggers ran into the same loop and worked around it on their side: filelog #3416342: Circular reference detected for service, raven #3269293: Circular reference detected for service (the error goes away when Layout Builder is uninstalled), watchdog_mailer #3414001: Site crashing with services circular references, commerce #3587604: Circular reference detected for service "Drupal\Core\Logger\LoggerChannelFactoryInterface".
The invalidator only needs the block manager when entity_field_info is invalidated. Proposed fix: inject a service closure (#[AutowireServiceClosure('plugin.manager.block')]) and only resolve it inside invalidateTags() for that tag. The class is @internal, so no BC layer needed.
Patch attached for 11.4.x (uses !service_closure in the YAML, on main the service is autowired so the MR will use the attribute). For a kernel test: a test module with a logger that depends on cache_tags.invalidator, and check that logger.channel.default can be fetched.
| Comment | File | Size | Author |
|---|---|---|---|
| core-extra-field-block-invalidator-service-closure.patch | 2.14 KB | bceyssens |
Issue fork drupal-3632318
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
bceyssensComment #4
bceyssensComment #5
smustgrave commentedCan you confirm if #3103620: Dependency on config storage causes circular reference in service container solves the issue please.
Comment #6
bceyssens#3103620 does not fix this. I applied !14205 on main without !17545 and ran the kernel test from !17545. It still fails:
Circular reference detected for service "logger.channel.default", path: "logger.channel.default -> logger.factory -> logger.layout_builder_logger_test -> cache_tags.invalidator -> plugin.manager.block".With !17545 added on top, it passes.
!14205 only changes the syslog logger. Our site does not have syslog enabled. The logger in our trace is from tmgmt_smartling_log_settings, which reads config in its constructor. filelog, raven, watchdog_mailer and commerce hit the same loop with their own loggers. #3609333 (closed as a duplicate of #3103620) shows the same tail: cache_tags.invalidator -> plugin.manager.block -> logger.channel.default.
!17545 removes the plugin.manager.block dependency from cache_tags.invalidator. It does not depend on what a logger does in its constructor. Both issues can be committed independently.
Generated with the help of an LLM.
Comment #7
smustgrave commentedSharing this as this is the 10th maybe issue I’ve seen with an AI post. Please review much appreciated
https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquett...