"Enforced" Dependencies of Optional Configs Overwrite Other Dependencies

Created on 4 November 2020, about 4 years ago
Updated 19 September 2023, about 1 year ago

Problem/Motivation

Due to the way that \Drupal\Core\Config\ConfigInstaller::getMissingDependencies() merges enforced dependencies into the larger dependency array, it actually overwrites other dependencies if they have matching keys (e.g. module). This can cause optional config to be installed as long as the enforced config dependency is met even when other dependencies are not.

Steps to reproduce

  1. Start with a clean install of Drupal that has no contrib modules installed.
  2. Create a new module (e.g. module_a) that defines an optional entity form display config that includes both of the following:
    • an enforced module dependency on the module_a module.
    • a regular module dependency on the readonly_field_widget module.

    For example:

    langcode: en
    status: true
    dependencies:
      enforced:
        module:
          - module_a
      module:
        - field_layout
        - layout_discovery
        - readonly_field_widget
        - text
    id: node.page.full
    targetEntityType: node
    bundle: page
    mode: full
    content:
      name:
        type: readonly_field_widget
        weight: 0
        region: content
        settings:
          label: above
          formatter_type: string
          show_description: 0
          formatter_settings:
            string:
              link_to_entity: 0
        third_party_settings: {  }
    
  3. Attempt to install module_a.
  4. Examine the form displays installed on the site for the target entity type (in the case above, examine the "full" display of "page" nodes).

The optional configuration should not be installed because the Read-only Field Widget module is not installed.

Drupal attempts to install the optional config, resulting in the following fatal error message:

The "readonly_field_widget" plugin does not exist. Valid plugin IDs for Drupal\Core\Field\WidgetPluginManager are: (...omitted...)

Stepping through this in the debugger, I can see that the module key of the dependencies is being overwritten by the array_merge():

Proposed resolution

\Drupal\Core\Config\ConfigInstaller::getMissingDependencies() should be modified to do a deep array merge instead of an array_merge().

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Fixed

Version

10.1

Component
Configuration 

Last updated 2 days ago

Created by

🇺🇸United States GuyPaddock

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024