domain_config caches library definitions per domain, so that a library built from configuration that is overridden per domain does not leak from one domain to another. It does that by decorating the core library discovery and adding the active domain to the cache id.

The decorated service is library.discovery.collector. Core deprecated that service in Drupal 11.1 (#3462970: LibraryDiscovery class is deprecated) and made library.discovery itself the LibraryDiscoveryCollector, and from 11.1 on nothing reads library.discovery.collector any more. On Drupal 11.1 and later the decoration is therefore never used and all domains share one library_info:THEME cache entry: whichever domain builds the definitions first serves them to the others until the cache is cleared. Drupal 10.2 to 11.0 are not affected, since there library.discovery is the LibraryDiscovery wrapper around library.discovery.collector.

Steps to reproduce

On a site running Drupal 11.1 or later with two domains, add a hook_library_info_alter() implementation that builds a library definition from a configuration value overridden per domain, then request the page that attaches the library on each domain in turn. Both domains serve the definition built for whichever domain was requested first.

Proposed resolution

This branch supports ^10.2 || ^11, so the decorated service has to be chosen at container build time rather than written into the service definition. Keep the definition on library.discovery.collector and add a DomainConfigServiceProvider whose alter() reads the container instead of the core version: when the class of the library.discovery definition is a LibraryDiscoveryCollector, call setDecoratedService('library.discovery') on the domain_config definition. Symfony resolves decoration during compilation, after alter() runs, so the definition read there is still the one core registered.

Moving the decoration to library.discovery unconditionally is not an option on this branch: on Drupal 10.2 to 11.0 the collector does not implement LibraryDiscoveryInterface, which library.discovery is aliased to, so every service type-hinting that interface would fail.

A kernel test should pin the behavior: two domains, a library whose definition is built from configuration overridden per domain, and the second domain must build its own definitions rather than read the cache entry the first domain wrote.

The 3.0.x branch carries the same service definition and the same core requirement, so the fix applies there as well. The 4.x branch needs none of this, since it requires ^11.4 || ^12 where library.discovery is always the collector; that change is #3612547: Complete Drupal 12 compatibility.

The merge requests also give DomainAccessDefaultValueAutocompleteTest a test group. That class carries none, neither the annotation nor the attribute, and run-tests.sh on Drupal 10 throws MissingGroupException before running anything, so the previous major test lane stopped at discovery and ran no test at all on either branch.

AI-Generated: Yes (Claude Code was used to help draft this issue summary. I reviewed it before posting; there is no code on this issue yet.)

Issue fork domain-3616863

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

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review

  • mably committed ce18a4ec on 3.x
    fix: #3616863 Per-domain library definitions are shared between domains...

  • mably committed 7e42db5f on 3.0.x
    fix: #3616863 Per-domain library definitions are shared between domains...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

mably’s picture

Issue summary: View changes

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.