46

I'm writing a custom module for Drupal 8. It defines a field storage configuration object, in a file called modules/mymod/config/install/field.storage.bloom_stem.bs_twitter_ac.yml.

The problem is that this is not removed when I uninstall the module; it is apparently left behind because, when I re-install the module, I get a crash.

drush -y pm-uninstall mymod
drush cr
drush -y en mymod

exception 'Drupal\Core\Config\PreExistingConfigException' with message 'Configuration objects (field.storage.bloom_stem.bs_twitter_ac) provided by mymod already exist in active configuration'

So it seems I need to some how manually remove this configuration object. Do I need to provide some more code that deletes it when the module is uninstalled?

2

15 Answers 15

58

The easiest way to do this at the moment is to use drush php (or core-cli) to open an interactive session.

Then use:

Drupal::configFactory()->getEditable('system.menu.devel')->delete();

This functionality will be added into Drupal console as well.

4
  • 1
    This perfectly solved the problem. Change 'system.menu.devel' to `the_setting.you.want.to.delete' Aug 16, 2016 at 16:26
  • What about removing multiple configs? e.g. migrate_plus.migration.*
    – Nic
    Sep 8, 2016 at 8:54
  • @Nic it's not pretty, but check out my solution on your other question to delete multiple: drupal.stackexchange.com/questions/214132/…
    – CR47
    Sep 8, 2016 at 21:50
  • If you have direct access to the database, very carefully delete the offending entries from the config table.
    – Naidim
    Dec 19, 2016 at 14:58
34

Drush command to delete configuration object: drush config-delete <config_name>.

3
  • in cases of multi-site, drush -l your.site.domain config-delete <config_name>
    – muskie9
    Apr 14, 2017 at 1:08
  • 2
    shortened format is drush cdel <config_name>
    – Sharique
    Mar 12, 2018 at 13:16
  • be mindful, if you delete any configs, you should also do a drush cr after to remove any cached config dependencies otherwise you may get something that looks like this: Error: Call to a member function getConfigDependencyKey() on null
    – wilco
    Jul 30, 2019 at 19:36
17

You can use the following methods. Use the following code in hook_uninstall

Drupal::configFactory()->reset('field.storage.bloom_stem.bs_twitter_ac');

OR

in the yml file you can put the dependencies like


dependencies:
  module:
    - yourmodule
  enforced:
    module:
      - yourmodule

then drupal will automatically remove this configurations on uninstalling your module as described by Berdir here https://drupal.stackexchange.com/a/173879/10436

7
  • 5
    This might have changed lately, but it is slightly different now. dependencies: enforced: module: - yourmodule
    – hw.
    Aug 13, 2016 at 14:43
  • 1
    @hw your comment is very important. Consider adding it to the answer, with a link to the relevant change record if possible. I couldn't find it. Jan 26, 2017 at 8:57
  • GAH!! I knew there was a way to do this, but I couldn't remember the "enforced:" part. This is the simplest, cleanest way to do it, especially when creating them in yml files. Mar 28, 2017 at 18:36
  • using this approach and trying to install the module, Drupal throws the error: Module custom_module cannot be enabled because it depends on the following modules which could not be found:
    – John
    Feb 9, 2018 at 15:46
  • Hi John, in case you didn't end up figuring it out, it sounds as though you may have put your module dependency in the wrong place. The configuration described in this answer is intended to go in YML file(s) in the config/install directory in your module. In the OP's case this would be in his/her config/install/field.storage.bloom_stem.bs_twitter_ac.yml file. It sounds as though you may have put the dependency in your module's mymodule.info.yml file instead (that will prevent your module from being able to install) Oct 3, 2018 at 23:16
10

Using the drupal console:

$ drupal config:delete 'the_config_to_delete'
2
  • 1
    Docs at: hechoendrupal.gitbooks.io/drupal-console/content/en/commands/… But can it do wildcards? e.g. drupal config:delete 'migrate_plus.migration.*'
    – Nic
    Sep 8, 2016 at 9:05
  • 2
    In the latest drupal console, config:delete expects you to specify the config type first, e.g. drupal config:delete active 'name' or `drupal config:delete staging 'name' (with only one parameter supplied, it'll assume you've given it the type and prompt you for the config name.) Dec 14, 2016 at 15:51
8

Drupal::configFactory()->reset() does not delete the config object. For this run Drupal::configFactory()->getEditable('field.storage.node.your_field_name')->delete()

4

Uninstall Active Configuration from Custom Module

I ran into the same problem trying to uninstall config files from a custom module. I have a custom module used to pass custom configuration files for webform. Since I'm not perfect I want to be able to uninstall the module, edit code and reinstall. I found if I referenced my custom module (my_module) in the dependencies/enforced section in the config/install yml file, when I uninstalled my module the configuration files would also uninstall.

   langcode: en
    status: true
    dependencies:
        enforced:
            module:
                - webform
                - my_module // reference your module here
4

I created a simple module that you can use to delete configuration items.

https://www.drupal.org/project/config_delete

4

Use hook_uninstall to remove the configuration, when the module is uninstalled.

Then delete the configuration:

function hook_uninstall() {
  \Drupal::configFactory()->getEditable('the_setting.you.want.to.delete')->delete();
}
3

You can remove all the configs you imported from config/install by implementing HOOK_uninstall():

function my_module_uninstall() {

  $module_path = \Drupal::service('extension.list.module')->getPath('my_module') . '/config/install';

  $configs = [];
  $files = \Drupal::service('file_system')->scanDirectory($module_path, '/\.yml$/');

  if ($files) {
    foreach ($files as $file) {
        $configs[] = $file->name;
    }

    foreach ($configs as $config_name) {
        \Drupal::configFactory()->getEditable($config_name)->delete();
    }

    return TRUE;
  }
}
1
  • Wow, this is the answer! Thank you
    – kopeboy
    Jul 7, 2023 at 14:27
2

You can use Drupal console to delete the active configuration, with drupal config:delete active config_to_delete.

2

All these answers recommend deleting the underlying config object directly, but the correct way is to delete the entity through the entity storage system.

For example, if you have an image style with ID "large" and you want to delete it, you should do this:

\Drupal::entityTypeManager()->getStorage('image_style')->load('large')->delete();

Doing it this way, core will invoke "predelete" before the config is deleted and "delete" hooks after the config is deleted, which other modules may rely on to perform various clean up operations.

1
1

Search for all the configurations listed using drush config-list Then identify the configuration that you would like to delete. Use the below command to delete the configuration drush config-delete

1

I could delete the active configuration using the drush config:delete command as below drush cdel "name of the config" for example in my case it was drush cdel dtn_apple_news.setting

after running this the configuration got deleted and then running drush en-y "module name" got the module to be installed.

0

Use Easy Install module to avoid this configuration issues, this module will allow to delete configurations while uninstalling a module, it works even if a module's configs not contains enforced in yml or not added configs in optional folder.

Configuration on uninstallation image

-1

I leave here a tiny (yet a bit over-engineered) Python script which removes the configuration leftovers. It relies on drush config-delete.

# 'batch_config_delete.py'
# 'drush' has to be available in the current directory

import os
import argparse
import subprocess

MODULES_ROOT = "/var/www/html/MYSITE/web/modules/custom"

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Batch config delete.")
    parser.add_argument("-m", "--module", required=True, help="Module name")
    args = parser.parse_args()
    install_path = os.path.join(MODULES_ROOT, args.module, 'config/install')

    for f in os.listdir(install_path):
        if f.endswith('.yml'):
            config_name = os.path.splitext(f)[0]
            print "Delete config:", config_name
            subprocess.call(['drush', 'config-delete', config_name])

Should be executed like this:

python ../scripts/batch_config_delete.py -m foobar
2
  • 1
    You are asking PHP developers to use a python script? Seems a bit silly.
    – Patrick
    Jul 31, 2017 at 20:37
  • Why Python on a PHP project? Mar 22, 2021 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.