Prevent Bootstrap Layouts plugin manager from mutating `container.namespaces` and limit discovery to enabled themes

Created on 26 July 2025, 4 days ago

Problem/Motivation

The BootstrapLayoutsPluginManager constructor currently:

  1. Mutates the shared container.namespaces by calling exchangeArray(), causing all other plugin managers (ActionManager, ViewsPluginManager, etc.) to scan the updated namespaces list.
  2. Merges in the entire Composer PSR‑4 map instead of a filtered list of enabled themes.

As a result, under Drush site installs, modules like Entity Print (which ship @Action plugins) trigger the core ActionManager, which immediately discovers FlagActionDeriver from the Flag module—even though Flag’s services aren’t yet registered—causing a ServiceNotFoundException: You have requested a non-existent service "flag". due to the fact that FlagActionDeriver tries to get flag service when it's instantiated.

Steps to reproduce

Versions:

  • Bootstrap Layouts 8.x-5.x-dev
  • Drupal core 10.5.1
  • Drush 13.6.1
  1. Create a fresh distribution profile web/profiles/custom/test_profile with test_profile.info.yml:
    name: Test
    type: profile
    core_version_requirement: '^10'
    distribution:
      name: Test
      langcode: en
    install:
      - bootstrap_layouts
      - entity_print
      - flag
    themes:
      - olivero
      - claro
  2. composer require drupal/flag drupal/entity_print drupal/bootstrap_layouts
  3. Run the site install with drush:
    drush site:install \
      --account-mail="admin@example.com" \
      --account-name="admin" \
      --site-mail="no-reply@example.com" \
      --site-name="Test" \
      -y -vvv
  4. Observe the exception:
    ServiceNotFoundException: You have requested a non-existent service "flag".

Expected behavior

  • Bootstrap Layouts must not mutate the global container.namespaces service.
  • It should only append PSR‑4 prefixes for enabled themes on a private copy of the namespace map.
  • All other plugin managers should continue to see exactly the kernel’s original namespace list (a filtered list of enabled modules and some other manually registered namespaces), so no plugin is discovered before its module is enabled and its services are registered.

Proposed resolution

  1. Avoid mutating the injected namespaces.
  2. Add only enabled themes to the private namespaces version.

Benefits of the fix

  • Restores correct plugin-discovery ordering.
  • Ensures global container.namespaces remains identical to the kernel’s compile-time list.
  • Limits scanning to only the modules/themes that are enabled.

Potential issues from the old implementation

  • Premature plugin discovery: Any plugin manager could trigger derivers before dependencies’ services exist, breaking installs or runtime behavior.
  • Performance impact: Scanning the full Composer PSR‑4 map for every plugin manager inflates memory usage and slows bootstrap.
  • Unexpected plugins: Disabled modules may expose plugin classes, leading to hard-to-debug side-effects.

Remaining tasks

  • ✅ File an issue
  • ➖ Addition/Change/Update/Fix
  • ➖ Testing to ensure no regression
  • ➖ Automated unit testing coverage
  • ➖ Automated functional testing coverage
  • ➖ UX/UI designer responsibilities
  • ➖ Readability
  • ➖ Accessibility
  • ➖ Performance
  • ➖ Security
  • ➖ Documentation
  • ➖ Code review by maintainers
  • ➖ Full testing and approval
  • ➖ Credit contributors
  • ➖ Review with the product owner
  • ➖ Release notes snippet
  • ❌ Release

API changes

  • N/A

Data model changes

  • N/A

Release notes snippet

  • N/A
🐛 Bug report
Status

Active

Version

5.0

Component

Code

Created by

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

Merge Requests

Comments & Activities

Production build 0.71.5 2024