Error when installing a recipe that has configuration files already in the system, even if there is no difference

Created on 1 October 2023, about 1 year ago
Updated 16 August 2024, 2 months ago

Problem/Motivation

When applying a recipe that has existing configuration that differs from the recipe's, you get the following error.

In ConfigConfigurator.php line 37:

  The configuration 'gin.settings' exists already and does not match the recipe's configuration

Steps to reproduce

Enable the Gin admin theme
Change a setting for that theme
Apply kanopi/gin-admin-experience recipe from Packagist
Witness Error.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

๐Ÿ› Bug report
Status

Postponed: needs info

Version

11.0

Component

Code

Created by

๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

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

Comments & Activities

  • Issue created by @thejimbirch
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

    This is also the case in dependencies of recipes.

    In this scenario, I am making content type recipes. I would like a base recipe that contains field.storage configs that will be used in multiple content types, and things like taxonomy.vocabulary configs that add taxonomies. saplings-content-base is the name.

    I then have a page and a post recipe (saplings-content-page and saplings-content-post) that add field.field configs, entity_form_displays, entity_view_displays, etc... Both of these recipes have a dependency on the base recipe, saplings-content-base.

    The first will import as expected. The second will error out at the import of configuration in the /config folder of the dependent recipe even though the config is exactly the same as it is in the system.

  • ๐Ÿ‡ฏ๐Ÿ‡ดJordan Rajab Natshah Jordan

    Faced the same issue, in number of cases.
    - run a recipe in code ( hook install )
    - run a recipe in a profile install

    Avoided by switching between action import to action simple config update.
    Should be or not.
    Is this the right action? or it should allow to re-import?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    Discussed this with @thejimbirch in Slack: https://drupal.slack.com/archives/C2THUBAVA/p1705605325427469?thread_ts=...

    For reference, I said:

    ...isnโ€™t [this] only an issue if two recipes provide the same named piece of config, but with some sort of difference between the two versions?

    To which Jim replied:

    No difference. It fails if it is the same also.

    That sounds like the true crux of the bug to me, so I'm updating the issue title to reflect that.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    I wonder...is it possible that key ordering is triggering the problem?

    We have this code in \Drupal\Core\Recipe\ConfigConfigurator::__construct():

            if ($active_data !== $recipe_storage->read($config_name)) {
              throw new RecipePreExistingConfigException($config_name, sprintf("The configuration '%s' exists already and does not match the recipe's configuration", $config_name));
            }
    

    PHP does not consider ['a' => 1, 'b' => 2] strictly equal to ['b' => 2, 'a' => 1] even though, for Drupal's purposes, they are functionally identical. So if two recipes provide the same config, but with different key ordering, could that trigger this bug?

    Maybe we should order the keys before doing the comparison? I can't think of any situations where config would be "different", from a functional perspective, due to key ordering.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    If we have:

    1. RecipeRunnerTest::testApplySameRecipe() which does not fail on this
    2. consistent steps to trigger this problem

    Then we should be able to observe the difference in the manual STR vs the existing test coverage and then expand the test coverage accordingly? ๐Ÿค“

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    I was able to reproduce this and I think it's a combination of a couple of things.

    First, my steps to reproduce:

    Now do drush cget gin.settings. You'll see that, except for the _core section's presence, it exactly matches what's in web/themes/contrib/gin/config/install/gin.settings.yml.

    Then, go to the theme settings page, and just submit the form. You don't need to change anything.

    But if you do drush cget gin.settings again, you'll see a number of extra things added by the theme system. This is part of where the mismatch comes from -- any theme settings config would suffer from this bug.

    But you'll also notice that third_party_settings has moved. In web/themes/contrib/gin/config/install/gin.settings.yml, it's the last key. After submitting the form, it's probably elsewhere. Because the recipe system doesn't normalize key order, this would still cause the bug, even if the theme system wasn't adding extra settings.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    I'm removing the "needs tests" tag until two things are figured out here:

    • We decide that we should in fact normalize the key order of config when comparing it (strong yes from me on this one, but that's just my opinion); that should happen in a separate issue with its own test coverage.
    • We handle the special-casing of theme settings. I think theme settings are very likely to be changed by recipes, so this is important to figure out. IMHO, the correct solution is to require theme settings to ship every key defined by core's theme_settings config schema type (and if they're not, treat it as a validation error that blocks the recipe from being applied). This is actually possible, now that we can validate that particular keys are present in a config object.
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
    1. +1 for separate issue in which we change
              if ($active_data !== $recipe_storage->read($config_name)) {
                throw new RecipePreExistingConfigException($config_name, sprintf("The configuration '%s' exists already and does not match the recipe's configuration", $config_name));
              }
      

      to not require an exact match (===/!==), but an equality match.

    2. We already know that theme_settings are a potentially problematic thing to compare because we observed in #3395555-22: Add validation constraints to olivero.settings โ†’ that for example olivero.settings cannot be marked fully validatable due to the parent config schema type (type: theme_settings) not being fully validatable!
      And them being fully validatable is actually what would be required to do

      Issue created: ๐Ÿ“Œ Add validation constraints to `type: theme_settings` Active .

    AFAICT the only hard blocker here is the one for #10.1, because it is about general infrastructure. The one for #10.2 is about one specific config schema type, so should not be a blocker.

    Marking but leaving the creation of the blocking issue to somebody else.

  • Status changed to Postponed 9 months ago
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts
  • Status changed to Active 9 months ago
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    #3416287: ConfigConfigurator should be insensitive to key order when comparing active config to recipe config โ†’ is in!

    With that being done, I'm not sure we actually need to prioritize this issue right now -- in fact, we might even be able to close it, because:

    We also don't need test coverage here, because it was added in #3416287: ConfigConfigurator should be insensitive to key order when comparing active config to recipe config โ†’ .

    Therefore...do we really need this issue? I think not...but I'll leave it open for now for Wim to close it out if he agrees with my assessment of the situation.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

    I enabled the gin theme.
    Applied the gin-admin-experience recipe
    Failed because of blocks.

    โฏ fin drush then -y gin
     [success] Successfully installed theme: gin
    
    โฏ fin recipe-apply gin-admin-experience
    
    In ConfigConfigurator.php line 37:
    
      The configuration 'block.block.gin_breadcrumbs' exists already and does not match the recipe's configuration
    
    
    recipe <path>
    

    I then changed some config in the Gin settings and got the original error.

    โฏ fin recipe-apply gin-admin-experience
    
    In ConfigConfigurator.php line 37:
    
      The configuration 'gin.settings' exists already and does not match the recipe's configuration
    
    
    recipe <path>
    
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

    I also tried a recipe dependency test. Both depend on the same base recipe.

    I may be doing something wrong though. I did a new composer install, I see the code from the closed issue in the patch on d.o

    โฏ fc require kanopi/saplings-content-page kanopi/saplings-content-post
    ./composer.json has been updated
    Running composer update kanopi/saplings-content-page kanopi/saplings-content-post
    Gathering patches for root package.
    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 2 installs, 0 updates, 0 removals
      - Locking kanopi/saplings-content-page (0.0.1)
      - Locking kanopi/saplings-content-post (0.0.9)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 2 installs, 0 updates, 0 removals
      - Downloading kanopi/saplings-content-page (0.0.1)
      - Downloading kanopi/saplings-content-post (0.0.9)
    Gathering patches for root package.
    Gathering patches for dependencies. This might take a minute.
      - Installing kanopi/saplings-content-page (0.0.1): Extracting archive
      - Installing kanopi/saplings-content-post (0.0.9): Extracting archive
    Generating optimized autoload files
    Hardening vendor directory with .htaccess and web.config files.
    > [ ! -f rector.php ] && cp vendor/palantirnet/drupal-rector/rector.php . || true
    > vendor/bin/phpcs --config-set installed_paths vendor/drupal/coder/coder_sniffer || true
    Using config file: /var/www/vendor/squizlabs/php_codesniffer/CodeSniffer.conf
    
    Config value "installed_paths" updated successfully; old value was "../../drupal/coder/coder_sniffer,../../sirbrillig/phpcs-variable-analysis,../../slevomat/coding-standard,vendor/drupal/coder/coder_sniffer"
    100 packages you are using are looking for funding.
    Use the `composer fund` command to find out more!
    PHP CodeSniffer Config installed_paths set to ../../drupal/coder/coder_sniffer,../../sirbrillig/phpcs-variable-analysis,../../slevomat/coding-standard,vendor/drupal/coder/coder_sniffer
    phpstan/extension-installer: Extensions installed
    Cleaning installed packages.
    No security vulnerability advisories found
    Using version ^0.0.1 for kanopi/saplings-content-page
    Using version ^0.0.9 for kanopi/saplings-content-post
    โฏ fin recipe-apply saplings-content-post
    
    
     [OK] Saplings - Post Content type applied successfully
    
    
     [success] Cache rebuild complete.
    โฏ fin recipe-apply saplings-content-page
    
    In ConfigConfigurator.php line 37:
    
      The configuration 'imagemagick.settings' exists already and does not match the recipe's configuration
    
    
    recipe <path>
    
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

    Yeah, I have to be doing something wrong. I just searched my code base for Sorts an array recursively, by key, alphabetically. which is part of the new patch and it is not found. I will try again later.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    #16:

    I then changed some config in the Gin settings

    That is not changed by #3416287: ConfigConfigurator should be insensitive to key order when comparing active config to recipe config โ†’ . That's expected behavior.

    Applied the gin-admin-experience recipe
    Failed because of blocks.

    This however I expected to be addressed by #3416287: ConfigConfigurator should be insensitive to key order when comparing active config to recipe config โ†’ โ€ฆ ๐Ÿค” Any idea why this would be happening, @phenaproxima?

    EDIT: AHHHH, I see now that @thejimbirch was probably running a version of Recipes that did not yet include the fix (see #18) ๐Ÿ˜…๐Ÿ‘ Whew, hoping @thejimbirch's second attempt has more success! ๐Ÿ˜„

  • Status changed to Postponed: needs info 9 months ago
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    Okay, postponing this until @thejimbirch tries again and reports back!

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia narendraR Jaipur, India

    If I undo commit https://git.drupalcode.org/project/distributions_recipes/-/merge_requests/70/diffs?commit_id=54f1dd7fdddde0fc53dc6c0f970ba54a934b7489 from https://git.drupalcode.org/project/distributions_recipes/-/merge_requests/70 and then run drush si -y empty && php core/scripts/drupal recipe core/recipes/standard, I get The configuration 'user.role.authenticated' exists already and does not match the recipe's configuration error.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia narendraR Jaipur, India

    Similarly, If we copy core.menu.static_menu_link_overrides.yml into any recipe config folder, this error will come as core.menu.static_menu_link_overrides.yml is also provided by core/config/install

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia imalabya Bangalore

    Facing a similar issue. Have a base Content type recipe that has a dependency on the core/recipes/editorial_workflow that has a workflows.workflow.editorial configuration.

    Now there are 2 scenarios one which works without an issue other one throws an error

    1. Page content type recipe have a dependency on the base Content type recipe. The Page content type recipe is applied when my profile recipe is applied and it applies successfully without any error.
    2. Article content type recipe also has a dependency on the base Content type recipe. However, the Article content type recipe is not applied during the profile recipe installation. So when the profile recipe is applied, I try to apply the Article Content type recipe it fails with the error The configuration 'workflows.workflow.editorial' exists already and does not match the recipe's configuration coming from the editorial_workflow recipe.
Production build 0.71.5 2024