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);
}
}
}
}
}