2

I am developing on a Drupal 9 site. I have found something a bit odd when running drush cim. There are a handful of configurations for which it DOES say there was a success, but when you run drush cim once again, it still says they are ready for import. Clearly there is something wrong.

I looked at the diff of one of them, and they all seem to be like this.

screenshot

It tries to change the line order.

I tried to manually edit the config in the database drush config:edit swiftmailer.message so that active (which is the database) matched staged. However, I once again ran the import, found it was in the same state, and found that when I once again ran drush config:edit swiftmailer.message, it was back to the way it was!!

Can someone explain to me how to get out of this circle?

4
  • Are you using the config split module?
    – Jaypan
    Jun 17 at 20:37
  • 2
    It looks like sorting drupal.org/node/3230199
    – cilefen
    Jun 17 at 23:10
  • @Jaypan no, I"m not using the config split module. Jun 19 at 2:43
  • @cilefen I believe I have seen that post during my searches. However, I still don't know what I"m supposed to do to fix this. If you have any thoughts, can you please share? Jun 19 at 2:44

1 Answer 1

2

This happens, unfortunately. It can happen by a module that was enabled in the past and it changes the configuration but wasn't refreshed by the developer. Most of the time this appears when you resave the config then it becomes visible this kind of problem. Also, one of the core versions changed or added order to the keys, which also caused this. Our team had this issue several times, mostly it can cause similar missing configs when you add an extra field, but if you don't resave all the displays then the extra field is missing from some of the configs and later on, when somebody saves it, it will appear.

In your case most likely that you did the core upgrade but did not save all the configs and exported them at that time so it remained hidden until now.

What I can suggest preventing this in the feature is to create a drush command which loads all the site configs and saves them (without any change) then export and commit. Then when you enable or do an upgrade you run that command and export the changes. This will "prevent" to have such problems later on in the 99% of the cases.

Like this (written by one of my collaguage), but there are some edge cases where this also does not save some of the configs:

<?php

declare(strict_types=1);

namespace Drush\Commands;

use Consolidation\AnnotatedCommand\CommandResult;
use Consolidation\SiteAlias\SiteAliasManagerAwareTrait;
use Drush\SiteAlias\SiteAliasManagerAwareInterface;

/**
 * Drush commands.
 *
 * @package Drush\Commands
 */
class Commands extends DrushCommands implements SiteAliasManagerAwareInterface {

  use SiteAliasManagerAwareTrait;

  /**
   * Checks if there is any noise/artifacts in config.
   *
   * Config artifacts is unwanted noise which is not detected by config:status
   * and can appear for some configuration entities after being re-saved
   * (e.g: when the site gets installed from config).
   * Some examples include computed fields or extra fields impacting view modes.
   *
   * @command config-artifacts
   * @aliases ca
   * @bootstrap full
   * @option resave
   *   Re-save all config before comparing.
   *
   * @usage drush config-artifacts
   *   Use this after install-clean.
   *   Detect artifacts without re-saving config (e.g: after clean-install).
   * @usage drush config-artifacts --resave
   *   Use this after install-clone or to resolve existing artifacts (then run
   *   config:export).
   */
  public function configArtifacts($options = ['resave' => FALSE]) {
    if ($options['resave']) {
      $this->resaveConfig();
    }

    $selfRecord = $this->siteAliasManager()->getSelf();

    /** @var \Consolidation\SiteProcess\SiteProcess $process */
    $process = $this->processManager()->drush($selfRecord, 'config-status');
    $process->mustRun();
    $output = $process->getOutput();

    if (!empty($output)) {
      $this->logger()->error(dt('Found config artifacts between DB and sync directory.'));
      return CommandResult::dataWithExitCode($output, self::EXIT_FAILURE);
    }
    else {
      $this->logger()->success(dt('No config artifacts found.'));
    }
  }

  /**
   * Re-Save all config entities.
   */
  protected function resaveConfig() {
    /** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
    $config_manager = \Drupal::service('config.manager');
    $config_factory = $config_manager->getConfigFactory();
    $names = $config_manager->getConfigFactory()->listAll();

    foreach ($names as $name) {
      if ($entity_type = $config_manager->getEntityTypeIdByName($name)) {
        if ($config = $config_factory->getEditable($name)) {
          $entity_storage = $config_manager
            ->getEntityTypeManager()
            ->getStorage($entity_type);
          $entity_storage->importUpdate($name, $config, $config);
        }
      }
    }
  }
  
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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