Circular reference detected for service

Created on 22 January 2024, 10 months ago
Updated 5 September 2024, 2 months ago

Problem/Motivation

After upgraded Drupal from 9.5 to 10.2, I noticed, that if I uninstall any drupal module, the site immediately crashes ("The website encountered an unexpected error. Try again later."), with the following error in Drupal's log:

Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException: Circular reference detected for service "plugin.manager.block", path: "plugin.cache_clearer -> plugin.manager.block -> logger.channel.default -> logger.factory -> logger.filelog -> token -> cache_tags.invalidator". in Drupal\Component\DependencyInjection\Container->get() (line 147 of core/lib/Drupal/Component/DependencyInjection/Container.php).

It doesn't matter, whether uninstallation of the module is done on Drupal GUI, or by using Drush command, the result is the same. I tried uninstalling different modules for a couple of times, no difference. The only module that could be uninstalled successfully was File Log itself.

To make matters worse, after the uninstall the site gets into an ambivalent state, because the module is disabled on the GUI, but entries are left in the database, which can cause further issues. As proof of this odd state, after a database update (either navigating to update.php, or by using Drush) the following warning appears in Drupal's log:

Module xyz has an entry in the system.schema key/value storage, but is not installed.

  • Drupal: 10.2.2
  • File Log: 2.1.1
  • PHP: 8.1.27 / 8.2.15

Steps to reproduce

  1. Install Drupal 10.2 with Standard profile
  2. Enable Filelog module
  3. Enable any module
  4. Uninstall any module

Proposed resolution

I think in File Log module the token system should be lazy loaded to avoid such a recursion. The attached patch seems to solve the problem.

Remaining tasks

Tests should be adapted to the new method.

🐛 Bug report
Status

Fixed

Version

3.0

Component

Code

Created by

🇭🇺Hungary searosin

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

Merge Requests

Comments & Activities

  • Open in Jenkins → Open on Drupal.org →
    Core: 10.2.1 + Environment: PHP 8.1 & MySQL 8
    last update 10 months ago
    6 pass, 4 fail
  • Issue created by @searosin
  • The last submitted patch, filelog.patch, failed testing. View results
    - codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

  • 🇭🇺Hungary searosin

    The new patch fixes some coding standards bugs, and tests have been adapted to the new method.

  • Open in Jenkins → Open on Drupal.org →
    Core: 10.2.x + Environment: PHP 8.1 & MySQL 8
    last update 10 months ago
    28 pass
  • Status changed to Needs review 10 months ago
  • Status changed to Needs work 10 months ago
  • 🇺🇦Ukraine mr_fenix

    I cannot confirm the issue after a basic installation of Drupal with the standard profile, version 10.2.2, and PHP version 8.2.14. Here are the steps I followed:

    1. Installed and enabled Filelog module, version 2.1.1.
    2. Cleared the cache.
    3. Then, I removed the Contact module.
    4. Cleared the cache again.
    5. Checked admin/reports/dblog log
    No errors were found as described in the issue.

    Therefore, maybe it's better to identify the root of the problem before merging this, as it might turn out that instead of the Filelog module, the Token module or some other module needs to be fixed.

    Moreover, it seems the 'cache_tags.invalidator' service should not depend on 'plugin.manager.block', because after running the Drush command:

    drush ev '
      $database = \Drupal\Core\Database\Database::getConnection();
      $service_name = "token";
      $partial_cid = "service_container:%";
      // It is supposed the cache_container table is used.
      $query = $database->select("cache_container", "c")
        ->fields("c", ["data"])
        ->condition("cid", $partial_cid, "LIKE");
      $result = $query->execute();
    
      if ($record = $result->fetchAssoc()) {
        $container = unserialize($record["data"]);
        if (isset($container["services"][$service_name])) {
          $service_definition = unserialize($container["services"][$service_name]);
          echo  var_export($service_definition, TRUE);
        } else {
          echo "Service $service_name not found in the cache_container.\n";
        }
      } else {
        echo "No matching $partial_cid entry found in cache_container.\n";
      }'

    result was:

    array (
      'class' => 'Drupal\\Core\\Utility\\Token',
      'arguments' => 
      (object) array(
         'type' => 'collection',
         'value' => 
        array (
          0 => 
          (object) array(
             'type' => 'service',
             'id' => 'module_handler',
             'invalidBehavior' => 1,
          ),
          1 => 
          (object) array(
             'type' => 'service',
             'id' => 'cache.default',
             'invalidBehavior' => 1,
          ),
          2 => 
          (object) array(
             'type' => 'service',
             'id' => 'language_manager',
             'invalidBehavior' => 1,
          ),
          3 => 
          (object) array(
             'type' => 'service',
             'id' => 'cache_tags.invalidator',
             'invalidBehavior' => 1,
          ),
          4 => 
          (object) array(
             'type' => 'service',
             'id' => 'renderer',
             'invalidBehavior' => 1,
          ),
        ),
         'resolve' => true,
      ),
      'arguments_count' => 5,
    )

    So, there is no 'plugin.manager.block' service and it should not be in your installations either.

    Can anyone experiencing this issue post result of the command here to confirm it?

  • 🇭🇺Hungary searosin

    To reproduce the issue, Layout Builder module must also be enabled.

    (Corrected) steps to reproduce

    1. Install Drupal 10.2 with Standard profile
    2. Enable Layout Builder module
    3. Enable Filelog module
    4. Enable any module
    5. Uninstall any module

    In this case the error is as follows:

    Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException: Circular reference detected for service "token", path: "token -> cache_tags.invalidator -> plugin.manager.block -> logger.channel.default -> logger.factory -> logger.filelog". in Drupal\Component\DependencyInjection\Container->get() (line 147 of core/lib/Drupal/Component/DependencyInjection/Container.php).

  • Status changed to Needs review 10 months ago
  • Status changed to RTBC 10 months ago
  • 🇺🇦Ukraine mr_fenix

    I managed to reproduce it stably and the patch works perfectly. Thanks!

    Here is the dependent service that is implemented using the interface
    https://git.drupalcode.org/project/drupal/-/blob/10.2.2/core/modules/lay...

    It also seems that the error could be interpreted as a bug in the Drupal core, or could even be interpreted as a flaw in the Drupal dependency injection concept.

  • 🇮🇳India ashetkar

    I have also faced "Circular reference detected for service" after 10.2 upgrade and patch #4 worked fine. Thanks @searosin.

  • Status changed to Needs work 4 months ago
  • 🇳🇱Netherlands gaele

    Patch does not apply to 10.3.

  • Status changed to Needs review 4 months ago
  • 🇳🇱Netherlands gaele

    Patch for 3.0.

  • First commit to issue fork.
  • Merge request !19Issue #3416342 - Update token service → (Merged) created by AstonVictor
  • Status changed to Fixed 3 months ago
  • 🇺🇦Ukraine AstonVictor

    thanks for the patch.

    fixed and merged

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024