A fresh drupal install with a profile that depends on the referenced gg_user module results in the following error from the gg_user feature module:

/Users/me/Sites/gg/vendor/bin/drush @self --site-name="Guitar Gate" --site-mail="no-reply@acquia.com" --account-name="admin" --account-pass="admin" --account-mail="no-reply@acquia.com" --uri=default --yes --verbose site-install "lightning" "install_configure_form.update_status_module='array(FALSE,FALSE)'"
Executing: mysql --defaults-extra-file=/private/tmp/drush_oj1m3I --database=gg --host=localhost --port=3306 --silent  < /private/tmp/drush_05QzDm > /dev/null
You are about to DROP all tables in your 'gg' database. Do you want to continue? (y/n): y
Sites directory /Users/me/Sites/gg/docroot/sites/default already exists -   [notice]
proceeding.
Executing: mysql --defaults-extra-file=/private/tmp/drush_Bh4qQI --database=gg --host=localhost --port=3306 --silent  < /private/tmp/drush_bKh1l4 > /dev/null
Executing: mysql --defaults-extra-file=/private/tmp/drush_BQATFl --database=gg --host=localhost --port=3306 --silent  < /private/tmp/drush_rDWuJv
Executing: mysql --defaults-extra-file=/private/tmp/drush_EZ7NnJ --database=gg --host=localhost --port=3306 --silent  < /private/tmp/drush_yOTs6d
Starting Drupal installation. This takes a while. Consider using the --notify global option.          [ok]
Drupal\Core\Config\PreExistingConfigException: Configuration objects (user.settings) provided by      [error]
gg_user already exist in active configuration in
/Users/me/Sites/gg/docroot/core/lib/Drupal/Core/Config/PreExistingConfigException.php:65
Stack trace:
#0
/Users/me/Sites/gg/docroot/core/lib/Drupal/Core/Config/ConfigInstaller.php(471):
Drupal\Core\Config\PreExistingConfigException::create('gg_user', Array)
#1
/Users/me/Sites/gg/docroot/core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php(132):
Drupal\Core\Config\ConfigInstaller->checkConfigurationToInstall('module', 'gg_user')
#2
/Users/me/Sites/gg/docroot/core/lib/Drupal/Core/Extension/ModuleInstaller.php(141):
Drupal\Core\ProxyClass\Config\ConfigInstaller->checkConfigurationToInstall('module', 'gg_user')
#3
/Users/me/Sites/gg/docroot/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php(83):
Drupal\Core\Extension\ModuleInstaller->install(Array, true)
#4
/Users/me/Sites/gg/docroot/profiles/contrib/lightning/lightning.profile(60):
Drupal\Core\ProxyClass\Extension\ModuleInstaller->install(Array)
#5 /Users/me/Sites/gg/docroot/core/includes/batch.inc(252):
lightning_install_module('gg_core', Array)
#6 /Users/me/Sites/gg/docroot/core/includes/form.inc(870):
_batch_process()
#7 /Users/me/Sites/gg/docroot/core/includes/install.core.inc(617):
batch_process(Object(Drupal\Core\Url), Object(Drupal\Core\Url))
#8 /Users/me/Sites/gg/docroot/core/includes/install.core.inc(538):
install_run_task(Array, Array)
#9 /Users/me/Sites/gg/docroot/core/includes/install.core.inc(115):
install_run_tasks(Array)
#10 /Users/me/Sites/gg/vendor/drush/drush/includes/drush.inc(726):
install_drupal(Object(Composer\Autoload\ClassLoader), Array)
#11 /Users/me/Sites/gg/vendor/drush/drush/includes/drush.inc(711):
drush_call_user_func_array('install_drupal', Array)
#12
/Users/me/Sites/gg/vendor/drush/drush/commands/core/drupal/site_install.inc(80):
drush_op('install_drupal', Object(Composer\Autoload\ClassLoader), Array)
#13
/Users/me/Sites/gg/vendor/drush/drush/commands/core/site_install.drush.inc(247):
drush_core_site_install_version('lightning', Array)
#14 /Users/me/Sites/gg/vendor/drush/drush/includes/command.inc(366):
drush_core_site_install('lightning', 'install_configu...')
#15 /Users/me/Sites/gg/vendor/drush/drush/includes/command.inc(217):
_drush_invoke_hooks(Array, Array)
#16 /Users/me/Sites/gg/vendor/drush/drush/includes/command.inc(185):
drush_command('lightning', 'install_configu...')
#17
/Users/me/Sites/gg/vendor/drush/drush/lib/Drush/Boot/BaseBoot.php(72):
drush_dispatch(Array)
#18 /Users/me/Sites/gg/vendor/drush/drush/includes/preflight.inc(68):
Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#19 /Users/me/Sites/gg/vendor/drush/drush/drush.php(12): drush_main()
#20 {main}
Command dispatch complete

Only one module defines the configuration in question and the core config module has not been used to export any configuration. Is it possible that features is unable to override the configuration that is provided by Drupal by default on a clean installation?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

grasmash created an issue. See original summary.

grasmash’s picture

Title: PreExistingConfigurationException for user fields » PreExistingConfigurationException for core user config
grasmash’s picture

Issue summary: View changes
grasmash’s picture

Issue summary: View changes
grasmash’s picture

Issue summary: View changes
grasmash’s picture

Issue summary: View changes
grasmash’s picture

Issue summary: View changes
nedjo’s picture

Category: Bug report » Support request

Is it possible that features is unable to override the configuration that is provided by Drupal by default on a clean installation?

Yes. If you install attempt to enable a module (features-produced or otherwise) that provides configuration that already exists on the site (whether because it was installed by the Standard install profile or from some other source), you will get an error. This is not an error in Features but a feature of Drupal core.

If you first enable the Features module on the site, you should be able to enable the module despite it re-providing configuration, because Features overrides the relevant core service to enable installation of a feature-type module despite pre-existing configuration. This exception is provided to facilitate the feature development process but is not intended to be used on a site built with a set of features.

If you wish to produce features that can be used to install new sites, you can do so by creating a custom features bundle and selecting to create an install profile for the bundle. This install profile will not include configuration items that are packaged into other features of the bundle (features set).

grasmash’s picture

Title: PreExistingConfigurationException for core user config » Prevent PreExistingConfigurationException by prioritizing features config
Status: Active » Needs review
FileSize
2.08 KB

I'm attaching a patch that introduces new default behavior for features to resolve this problem. If a feature is enabled and it defines config that is already present in active configuration, the active configuration values will be deleted and the feature configuration will be imported. This can be disabled by setting $settings['features_overwrite_preexisting_config_on_install'] to FALSE in settings.php.

Please let me know if this is a desirable patch. If it is determined that the behavior is not desired, we can either disable it by default or I can move this to a small add-on contributed module (not really preferred).

Status: Needs review » Needs work

The last submitted patch, 9: 2825834-9.patch, failed testing.

nedjo’s picture

@grasmash: Thanks for the draft patch. I'd assumed from the original post that you were hitting this error when trying to enable a features module on a site where Features itself was not installed. Features is supposed to already allow you to install feature-type modules despite pre-existing conifguration. We make this exception by overriding (actually, decorating) the config.installer service. Can you confirm? If that's not working for you, we have a bug.

That said, your approach here may be preferable to what we're currently doing, since it doesn't resort to altering an existing service.

grasmash’s picture

Status: Needs work » Needs review
FileSize
2.86 KB

Features is supposed to already allow you to install feature-type modules despite pre-existing conifguration.

I can confirm that this is not working.

Take the following scenario.

  • I install Drupal with profile MyProfile, which defines a dependency on mybundle_license.
  • mybundle_license depends on license and features. it is a feature and contains a mybundle_license.features.yml file.
  • license provides license.license_type.yml
  • mybundle_license provides license.license_type.yml

When I run `drush si MyProfile` a PreExistingConfigurationException is thrown because both license and mybundle_license provide license.license_type.yml config. Features is necessarily enabled because mybundle_license depends on it.

Attaching an updated patch. This changed approach allows the behavior to be defined per feature in the *.features.yml file.

grasmash’s picture

Fixing feature info.

grasmash’s picture

Alright, so it turns out I didn't keep my changes atomic enough and actually defining a dependency on "features" in the feature module is sufficient to workaround this issue. Can we perhaps do that by default with exported features? Or, at least display a message to that effect?

nedjo’s picture

defining a dependency on "features" in the feature module is sufficient to workaround this issue. Can we perhaps do that by default with exported features?

In designing Features for Drupal 8, we explicitly decided it would be a tool for developing features, not for installing or supporting them on client sites. See the Principles page in the Features for Drupal 8 handbook:

The module should never be required on any client site in order for the functionality it packages to be available.

The issue you're coming up against is: in my module, how can I reprovide or override configuration that was provided by an other module already installed on the site? This is a generic issue and so beyond the scope of what we're doing in Features.

The easy answer is, put your overrides in the install profile, where overriding configuration is supported. But this isn't always feasible.

For another option, see the Configuration Rewrite module, which provides support for full or partial overrides.

nedjo’s picture

Status: Needs review » Active
+++ b/src/FeaturesManager.php
@@ -304,8 +304,8 @@ class FeaturesManager implements FeaturesManagerInterface {
-      if (!empty($module_list[$module])) {
-        $extension = $module_list[$module];
+      if (!empty($module_list[$module_name])) {
+        $extension = $module_list[$module_name];

Thanks for catching this bug. I've moved this portion of the patch to a new issue, #2828870: Variable name error in FeaturesManager::loadPackage().

liquidcms’s picture

I installed Commerce on site2 but have been setting up Commerce config on site1. I would like to transfer my commerce config from site1 to site2 but when i try to enable my commerce feature on site2 i get a ton of " already exist in active configuration" errors preventing me from installing.

Is this the issue reported here?

Was this not possible in D7 features ("revert")?

Does this patch fix the issue? And if it does.. why has it not been committed in the past 3 years?

liquidcms’s picture

hmm.. i think i saw above (or elsewhere) that adding Features as a module dependency would fix this. I didn't understand; but sure enough... once i installed Features on site2 i was able to enable my new feature module (and i guess overwrite existing config). :)

mohit_aghera’s picture

Status: Active » Needs review
FileSize
1.71 KB

The suggested approach worked for me and I am using it.

I need to re-roll the patch due to following changes:

+++ b/src/FeaturesManager.php
@@ -304,8 +304,8 @@ class FeaturesManager implements FeaturesManagerInterface {
+        $extension = $module_list[$module_name];

This section is already present in the latest 8.x-3.12 release. So patch fails on composer install.

file_scan_directory is deprecated so it isn't present in D9

+++ b/features.module
@@ -54,3 +54,40 @@ function features_modules_installed($modules) {
+  if (file_exists($config_install_dir) && $files = file_scan_directory($config_install_dir, '/^.*\.yml$/i')) {
+    foreach ($files as $file) {
+      // Parse the rewrites and retrieve the original config.

file_scan_directory is deprecated so it isn't present in D9