Skip to main content
Drupal: Handling Module Dependencies with Service Tags

Drupal: Handling Module Dependencies with Service Tags

When working with Drupal, you’ll often encounter situations where one module depends on another. This dependency ensures that the dependent module can only function if the required module is enabled. However, when it’s time to uninstall or remove a module, these dependencies can cause issues.

For example, imagine you created a custom module (my_module) that depends on another module (other_module). If you try to uninstall other_module without removing the dependency, Drupal won’t let you proceed. Instead of manually editing .info.yml files or risking accidental breakage, we can leverage service tags to handle dependencies in a cleaner way.

Common Problem

If you attempt to uninstall a module with existing dependencies, you’ll see an error like:

The following modules cannot be uninstalled because they are required by other modules: other_module

This happens because my_module.info.yml explicitly declares:

dependencies:
  - other_module

To safely uninstall without hacking .info.yml, we can dynamically alter dependencies using a service subscriber.

Solution: Using Service Tags

Drupal allows us to alter a module’s dependency behavior at runtime by subscribing to specific services. For module uninstallation, the service we want is:

  • module_handler (to alter module dependencies).

By defining a custom service tagged as event_subscriber, we can intercept uninstall events and dynamically remove the dependency.

Step 1: Create a Service Subscriber

Inside your custom module (my_module), add a service file:

my_module.services.yml

services:
  my_module.dependency_alter:
    class: Drupal\my_module\EventSubscriber\DependencyAlterSubscriber
    tags:
      - { name: event_subscriber }
Step 2: Implement the Subscriber

Create the class:

src/EventSubscriber/DependencyAlterSubscriber.php

<?php

namespace Drupal\my_module\EventSubscriber;

use Drupal\Core\Extension\ModuleUninstallValidatorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Alters module uninstall validation to remove custom dependencies.
 */
class DependencyAlterSubscriber implements EventSubscriberInterface, ModuleUninstallValidatorInterface {

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // Subscribe to module uninstall validation.
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function validate($module) {
    $reasons = [];
    // Skip dependency validation for 'other_module'.
    if ($module === 'other_module') {
      // Do nothing, allow uninstall.
    }
    return $reasons;
  }
}
Step 3: Register as a Validator

Tell Drupal that this class implements uninstall validation by tagging it:

my_module.services.yml

services:
  my_module.dependency_alter:
    class: Drupal\my_module\EventSubscriber\DependencyAlterSubscriber
    tags:
      - { name: module_uninstall_validator }
Step 4: Clear Cache & Test
  1. Run:

drush cr

   2. Try uninstalling the dependent module:

drush pmu other_module

  3. It should uninstall successfully, even though my_module was depending on it earlier.

Why Use This Approach?

  • No hacking .info.yml files – Keeps module metadata clean.

  • Dynamic dependency handling – You can control uninstall behavior at runtime.

  • Safe and Drupal-friendly – Uses service tags, aligns with Drupal best practices.

Dependencies are important for module stability, but when it comes to uninstallation, being able to bypass or alter them safely is critical. By using service tags with uninstall validators, you can remove custom module dependencies dynamically, ensuring a smooth and controlled uninstall process without risking core integrity.