Problem/Motivation

I work on LocalGov Drupal and since the 11.2 beta some of our tests have started failing with the following error;

Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by <em class="placeholder">localgov_paragraphs</em> have unmet dependencies: <em class="placeholder">core.entity_view_display.paragraph.localgov_contact.default (filter.format.wysiwyg)</em> in Drupal\Core\Config\UnmetDependenciesException::create() (line 100 of /app/web/core/lib/Drupal/Core/Config/UnmetDependenciesException.php).

This works fine under Drupal 10.4.x and Drupal 11.1.x and only seems to affect Drupal 11.2.x

From investigating, even though there is a config dependency for "filter.format.wysiwyg" it says it's an unmet dependency despite the install profile installing the "filter" module and "localgov_media" installing the wywiwyg format. From what I can tell it tries to install the dependencies in the wrong order.

Steps to reproduce

  1. Clone https://github.com/localgovdrupal/localgov_project/tree/3.2.x
  2. Change drupal core to 11.2.0-rc1@RC
  3. Install the "LocalGov Drupal" profile via the web UI or run the following phpunit test (phpunit --filter='ParagraphsAdministrationTest::testParagraphsTypes' /app/web/modules/contrib/localgov_paragraphs)

Comments

millnut created an issue. See original summary.

cilefen’s picture

Would you execute a git bisect operation on a working copy Drupal Core to find the commit that caused this?

cilefen’s picture

Oh, I guess you can't because this is a distro. Hmm...

millnut’s picture

Some further debugging information;

10.4.8 = OK
11.1.8 = OK
11.2.0-beta1@beta = FAIL
11.2.0-rc1@RC = FAIL

Looking at composer changes, the only difference is Symfony components from 7.2 to 7.3 and Drupal core from 11.1.8 to 11.2.x

millnut’s picture

Ok some more debugging after going through the git history of Drupal/Core this failure was introduced by this commit https://github.com/drupal/core/commit/3c297956866bd5f003643770febdbd16a9... from this issue https://www.drupal.org/project/drupal/issues/3416522.

Using the commit before https://github.com/drupal/core/commit/154480b82ac75aaa4d6d45696f8de92e7b... the installation goes through correctly without incorrect unmet dependencies.

nicxvan’s picture

Have you tried adding the filter module dependency?

https://git.drupalcode.org/project/localgov_paragraphs/-/blob/2.x/localg...

You don't have the dependency specified, I think that will likely fix the issue.

millnut’s picture

Hi nicxvan yep, I made the change https://github.com/localgovdrupal/localgov_paragraphs/pull/252/files and same error from both phpunit and web ui install and selecting the profile.

I've also tried `container_rebuild_required: false` and `container_rebuild_required: true` with no luck also

nicxvan’s picture

I wonder if there is another hidden dependency

stephen-cox’s picture

Looking at a single test: https://git.drupalcode.org/project/localgov_paragraphs/-/blob/2.x/module...

This fails on Drupal 11.2 with:

Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by localgov_homepage_paragraphs have unmet dependencies: field.field.paragraph.localgov_featured_campaign.localgov_featured_campaign_image (media.type.image)

The media.type.image config item is provided by the localgov_media module (https://git.drupalcode.org/project/localgov_core/-/blob/2.x/modules/loca...), but is optional config. Moving the YML file into the install directory fixes the test; all config items install without any errors.

Has the way optional config is installed changed? It certainly seems that optional config is not being installed when it should be.

stephen-cox’s picture

I've done a bit more digging into this. The LocalGov Media module uses hook_modules_installed to force the install of the optional config in the module (https://git.drupalcode.org/project/localgov_core/-/blob/2.x/modules/loca...), but this hook is not being called before the dependencies for the config in localgov_homepage_paragraphs are being calculated. Which means the config validation is failing.

It's clearly not good to have config that is going to be installed rely on optional config. The reason it currently works this way is much of the config in the media module is copied from the standard profile and would cause errors if the module was enabled with this profile rather than the LocalGov profile.

Ideally, we would want to delay the calculation of dependencies for some modules until after others are enabled. `container_rebuild_required: true` doesn't seem to be doing this.

nicxvan’s picture

Yeah there was some shuffling of when config is installed.

I think doing the config operations in that hook is generally iffy even if it worked previously.

I pinned @alexpott since I know he worked in this a fair bit.

alexpott’s picture

@stephen-cox try adding container_rebuild_required: true to modules/localgov_media/localgov_media.info.yml - this should fix this.

stephen-cox’s picture

> try adding container_rebuild_required: true to modules/localgov_media/localgov_media.info.yml

Unfortunately, this doesn't seem to fix things - I've tried adding `container_rebuild_required: true` to all the LocalGov Drupal modules loaded in the tests and they still fail. Using Xdebug to check when hook_modules_installed is called, it looks like config dependencies are calculated before this hook whether `container_rebuild_required` is true or not.

gt-harrison’s picture

I am seeing a similar issue with a custom module - in 11.1 and prior, the module installs without issue. With 11.2 (specifically 11.2.2), the install fails with error:

Unable to install [my module] due to unmet dependencies: field.field.block_content.call_to_action.field_remote_video (media.type.remote_video), field.field.block_content.topper.field_topper_image (media.type.image)

media is a required dependency of the module.

dependencies:
...
  - drupal:media
...
tonypaulbarker’s picture

Interesting that @gt-harrison also experiences an issue with media dependencies.

Further insights:

In the LocalGov Drupal case that @millnut and @stephen-cox has raised, test results are certainly different between 11.1 and 11.2.

We might make some distinction between tests and a full installation. One reason is that in test scenarios container rebuild doesn't appear to get the opportunity to run between steps at all?

Moving image type configuration to 'install' directory instead of 'optional' means that tests pass.

Has something changed in 11.2 with configuration validation?

I could not find any deprecation notices running the same in 11.1 and I couldn't pinpoint a change that tallies with observations.

I wondered if the suite of changes mentioned in https://www.drupal.org/node/3362879 have some bearing - that some new validation can have been activated that misses the 'optional' cases. Something with media type validation?

smulvih2’s picture

I am experiencing the same issue with the Drupal WxT distribution. Our automated tests began failing immediately after upgrading to Drupal 11.2.x. The first failures appeared around missing bundle configuration where we had YAML in /config/optional.

Specifically, media.type.image.yml lived in a profile sub-module under /config/optional. Under 11.1.x this installed without issue, but in 11.2.x it now fails with:

Missing bundle entity, entity type media_type, entity id image.

Moving that file to /config/install resolved the media error, but the failure reappeared for another bundle:

/config/optional/block_content.type.basic.yml

After fixing both of these by moving them to /config/install, the installer then began failing during config_rewrite, specifically for:

/config/rewrite/metatag.metatag_defaults.taxonomy_term.yml

The error:

Tried to rewrite config metatag.metatag_defaults.taxonomy_term via wxt_ext_metatag module without initial config present.

All dependencies in the relevant *.info.yml files are correct, and the modules that originally provide the config (e.g., Metatag) are declared as dependencies on our modules.

@millnut thanks for identifying the commit that broke this for distributions! It looks like Drupal 11.2.x introduced major changes to how module configuration is validated and installed:

  1. Modules are now validated and installed in batches, not individually. This means all default config across a group of modules is validated together before any of them install. If one module references a bundle/config provided by another module, and that config is in /config/optional or not present in the install profile's exported config, the entire batch now fails validation.
  2. Config install is now split into phases: InstallSimple -> InstallEntities -> Optional. Bundles placed in /config/optional don’t get created until the "Optional" phase, which now runs after entity display and field config that depends on those bundles. This exposes hidden ordering problems that used to work by accident (and were always a bit finicky).
  3. Profile-based installs no longer see a module's /config/install as part of the "initial config set". If a distribution rewrites config from contrib modules (e.g., Metatag) but the profile does not export that base config, config_rewrite now reports "initial config missing".

For Drupal WxT, we have several profile extensions that are optionally enabled (e.g., wxt_ext_metatag adjusts Metatag defaults to align with Government of Canada standards). With these installer changes, it appears we can no longer rely on optional profile modules to safely provide or rewrite configuration. We may now need to declare more dependencies directly on the profile itself, making the configuration more "all or nothing".

Given these changes, this might push us towards a recipe-based approach, where optional configuration can be applied deterministically and without depending on installer timing or profile-owned config.

joseph.olstad’s picture

I suggest moving this discussion over to the #maintainers or #d11readiness channels in Slack to see what kinds of pragmatic approaches would be possible.

joseph.olstad’s picture

Suggest having a look at the related change records for core.

This might lead to the most pragmatic solution.

New container_rebuild_required key in .info.yml files

Change \Drupal\Core\Config\ConfigInstaller to support installing multiple modules with a single container rebuild

joseph.olstad’s picture