Problem/Motivation

When flushing all caches on the Performance page (or using the link of admin_menu module), I get WSOD and this message in the logs.
Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException: Circular reference detected for service "Drupal\menu_link_content\Hook\MenuLinkContentHooks", path: "Drupal\menu_link_content\Hook\MenuLinkContentHooks -> plugin.manager.menu.link -> Drupal\Core\Menu\MenuTreeStorageInterface -> cache_tags.invalidator -> cache.static". in Drupal\Component\DependencyInjection\Container->get() (line 143 of /var/www/html/web/core/lib/Drupal/Component/DependencyInjection/Container.php).

This error does not occur when flushing with drush.

The circular dependency is triggered by the entity_type_alter hook inside MenuLinkContentHooks

Steps to reproduce

I can't provide clear steps at this time.
This occured in Drupal 11.4.1 I just updated from 10.something as I was flushing the caches using the UI (Performance page or admin_menu link).
There are a number of contrib modules installed, which might be involved in triggering it...I've checked my custom module, I doubt they are the problem.

It does not seem to occur on another site running on version 10.3.8.
UPDATE: I have just updated another site to 11.4.1 and have not experienced this error, which means - as was likely - that some contrib module is involved in triggering it.

Proposed resolution

Although it is not clear exactly what triggers the error, having seen the inside of \Drupal\menu_link_content\Hook\MenuLinkContentHooks.php I DO have a proposal, which incidentally gets rid of this issue.

The file contains a number of hooks, some of which require services to be injected...but not all of them require all those services, including the 'entity_type_alter' hook, which requires none.
Moving the 'entity_type_alter' hook to a new class - without services in the constructor - got rid of the error for me.

I'm not sure what the recommendations/best practices regarding this situation are, but to me it feels wrong to inject services unnecessarily.

I would propose separating the various hooks into separate classes based on what services they require.

Remaining tasks

- Move hooks into separate classes based on their required services.

User interface changes

None

Introduced terminology

None

API changes

None

Data model changes

None

Release notes snippet

CommentFileSizeAuthor
#4 3608799-4.patch1.91 KBmichaelsoetaert

Comments

karol haltenberger created an issue. See original summary.

ryan-l-robinson’s picture

I'm not sure how helpful this will be, but there are some similarities to one I just solved in the log_stdout contrib module: https://www.drupal.org/project/log_stdout/issues/3609942 That one also referenced menu_link_content, but only after log_stdout. The part that I actually fixed was in log_stdout to make the constructor more "dumb" only passing through the service to a property, not altering it on the way through.

The MenuLinkContentHooks constructor doesn't have the same problem and your error doesn't reference another module like mine did, but along with your experiment of putting that hook into a different file with a constructor that doesn't have services, it does seem to at least narrow down that the problem is around the constructor.

Something definitely got stricter with 11.4 because I found a couple other "circular reference" issues that started after that update, but they might not all have the same fix as mine.

karol haltenberger’s picture

Title: Possible circular service dependency when flushing caches through UI (MenuLinkContentHooks) » Circular service dependency error due to unintended/unnecessary dependencies in MenuLinkContentHooks.
Issue summary: View changes
michaelsoetaert’s picture

StatusFileSize
new1.91 KB

We ran into the same issue and moving hook entityTypeAlter to a separate file indeed fixed the issue.
This is most likely not the proper fix for the issue, but it could unblock you for the time being.
Attached patch contains these changes.