Problem/Motivation

A configuration import fails when these conditions are true:

  • A language override of a configuration object exists in the active storage and in the sync storage.
  • The sync storage changes the language override.
  • The sync storage changes the base configuration so that no key of the active language override exists in it any more.

The config importer first updates the base configuration. This saves the configuration and calls LanguageConfigFactoryOverride::onConfigSave(). This method calls filterOverride() for each language. filterOverride() removes the override keys that do not exist in the base configuration. When no keys are left, it deletes the override from the active storage.

Then the importer processes the language.* collection. The changelist contains an update for the override, but the override is not in the active storage any more. The import stops with this error:

Update target "views.view.frontpage" is missing.

The deployment of sites that use one drush cim call fails.

Steps to reproduce

  1. Install Drupal with the Standard profile and enable the Language module.
  2. Add the German language.
  3. Create a German override for views.view.frontpage that contains only the title of the feed display:
    <?php
    \Drupal::languageManager()
      ->getLanguageConfigOverride('de', 'views.view.frontpage')
      ->setData(['display' => ['feed_1' => ['display_title' => 'Feed DE']]])
      ->save();
    ?>
    
  4. Export the configuration (drush cex).
  5. In the sync directory, make these changes:
    • In views.view.frontpage.yml, remove the display feed_1.
    • In language/de/views.view.frontpage.yml, replace the content with:
      display:
      page_1:
      display_title: 'Seite DE'
  6. Import the configuration (drush cim).

Expected result: The import succeeds. The view has no feed_1 display. The German override contains only the title of page_1.

Actual result: The import fails with Update target "views.view.frontpage" is missing.

A site builder can create the same state in the UI: delete a display that has the only translated value, then translate a different display, export, and import on a site that still has the old state.

Proposed resolution

During a configuration synchronization, the importer writes the override collections itself. The filtering in LanguageConfigFactoryOverride::onConfigSave() is not necessary then, and it changes the active storage before the importer reaches the language.* collection.
Return early from onConfigSave() when \Drupal::isConfigSyncing() is TRUE:

<?php
public function onConfigSave(ConfigCrudEvent $event) {
  // During a configuration synchronization the importer writes the override
  // collections itself. Filtering here could delete an override that the
  // importer is about to update, which fails with "Update target is missing".
  if (\Drupal::isConfigSyncing()) {
    return;
  }
  // ...
}
?>

#3545595: Do not install language overrides for new languages during config sync uses the same approach for ConfigurableLanguage::postSave().

This issue changes only onConfigSave(). #3250066: Config import failing if language override is updated while original is recreated covers the related problem when the base configuration is recreated with a new UUID.

Remaining tasks

  • Write a kernel test that imports the configuration with ConfigImporter.
  • Create an MR.
  • Review.

User interface changes

None.

Introduced terminology

None.

API changes

None.

Data model changes

None.

Release notes snippet

None.

Issue fork drupal-3631598

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

tobiasb created an issue. See original summary.

tobiasb’s picture

Assigned: tobiasb » Unassigned
Issue summary: View changes
Status: Active » Needs review
tobiasb’s picture

Issue summary: View changes