Problem/Motivation

Sites on Drupal core 11.3.x can no longer install or update Admin Toolbar with Composer. The Composer metadata served by packages.drupal.org for drupal/admin_toolbar 3.6.x now lists "drupal/toolbar": "*" as a requirement, and nothing on 11.3.x can satisfy it.

The module's own composer.json does not declare this requirement. It appears to come from the drupal:toolbar dependency in admin_toolbar.info.yml, which the Drupal.org packaging now maps to the new drupal/toolbar contrib project.

On core 11.3.x the requirement cannot be met:

  • drupal/toolbar 2.0.0 requires drupal/core ^11.5 || ^12.
  • No drupal/core 11.3.x release declares "replace": {"drupal/toolbar": "*"}.

The requirement seems to have been added to the metadata of releases that were already published. Sites that already have a lock file keep working until Composer re-resolves core or Admin Toolbar, for example when applying an 11.3.x security release. At that point composer update fails, which blocks core security updates on any 11.3.x site that uses Admin Toolbar.

Steps to reproduce

  1. Create an empty directory with this composer.json:
    {
      "name": "example/admin-toolbar-repro",
      "type": "project",
      "repositories": [{"type": "composer", "url": "https://packages.drupal.org/8"}],
      "require": {
        "drupal/core-recommended": "11.3.19",
        "drupal/admin_toolbar": "^3.6"
      },
      "minimum-stability": "stable",
      "config": {"platform": {"php": "8.3.0"}, "allow-plugins": true}
    }
    
  2. Run composer update --dry-run.

Expected: Composer resolves Drupal core 11.3.19 with Admin Toolbar 3.6.3.

Actual:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires drupal/admin_toolbar ^3.6 -> satisfiable by drupal/admin_toolbar[3.6.0, 3.6.1, 3.6.2, 3.6.3].
    - Root composer.json requires drupal/core-recommended 11.3.19 -> satisfiable by drupal/core-recommended[11.3.19].
    - drupal/admin_toolbar[3.6.0, ..., 3.6.3] require drupal/toolbar * -> satisfiable by drupal/toolbar[2.0.0], drupal/core[10.6.19, 11.4.10].
    - drupal/core-recommended 11.3.19 requires drupal/core 11.3.19 -> satisfiable by drupal/core[11.3.19].
    - drupal/toolbar 2.0.0 requires drupal/core ^11.5 || ^12 -> found drupal/core[dev-main, 11.5.x-dev, 11.x-dev, 12.0.0-alpha1, ..., 12.x-dev (alias of dev-main)] but it does not match your minimum-stability.
    - You can only install one version of a package, so only one of these can be installed: drupal/core[10.6.19, 11.3.19, 11.4.10].

Workaround

Add the following to the root composer.json:

"provide": {
    "drupal/toolbar": "*"
},

This must be removed before the site moves to a core version where Toolbar is installed from the contrib drupal/toolbar project. Otherwise Composer will skip installing it.

Proposed resolution

I am not sure whether this belongs in this queue, the core queue, or the Drupal.org infrastructure queue. Please move it if another queue is a better fit. Possible fixes:

  • Change the Drupal.org packaging so that a drupal:toolbar dependency does not produce an unsatisfiable drupal/toolbar requirement for releases that support core 11.3.x.
  • Backport the "replace": {"drupal/toolbar": "*"} entry to the 11.3.x branch in core.
  • Until one of the above lands, document the root provide workaround and when to remove it on the Admin Toolbar project page or README.

Remaining tasks

  • Confirm where the drupal/toolbar requirement in the published metadata comes from.
  • Agree on which project owns the fix.
  • Implement and verify that drupal/admin_toolbar resolves on core 11.3.x without a root provide entry.

User interface changes

None.

API changes

None.

Data model changes

None.

AI Discloser: I used GitHub CoPilot while drafting this issue to help write the issue and also to confirm the bug with a default install of Drupal core 11.3.19 and admin_toolbar.

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

matthand created an issue. See original summary.

asherry’s picture

I'm having this issue as well with Drupal version 10.6. I get the issue now, thanks for the workaround. That's good enough for me while this is sorted out.

liam morland’s picture

We are having this problem and the workaround works for us.

matthand’s picture

Title: Cannot update to latest 11.3.19 core version due to impossible drupal/toolbar dependency » Cannot update to latest 11.3.x or 10.6.x core version due to impossible drupal/toolbar dependency
Priority: Normal » Major

Updating title to reflect it's also an active issue for Drupal Core 10.6.x as well. And raising this to major since it's likely blocking the update to fix the latest CVE for anybody that cannot easily edit their project's composer.json file.

Saw in Slack that not backporting the replace fix to Core 11.3.x was intentional decision. Strange the infrastructure is adding the drupal/toolbar dependency on admin_toolbar's composer.json for both 10.6.x and 11.3.x. To unblock folks right away we could move the workaround into this module.

Make a new v4 release of admin_toolbar for Drupal 11.5 and 12. Then, set the v3 to be compatible with Drupal core less than 11.5 and include a "provide" or "replace" key workaround in the modules composer.json file.

dydave’s picture

Sure.
No problem.

What could we include in the module's 3.x branch to help fix this issue?

Or should the code changes be made at another level?
We're seeing the same issue for the contrib Toolbar module: #3631159: Toolbar update breaks dependent modules and sites using 11.2-11.4.

matthand’s picture

@dydave, you can add a "provide" or "replace" key with the value of "drupal/toolbar: *" to this module's composer.json. It will work from anywhere in the dependency tree. I feel the "provide" key was more proper myself but either seem to technically work, and Core chose "replace".

Here's the explanation from Composer techdocs:

replace#
Map of packages that are replaced by this package. This allows you to fork a package, publish it under a different name with its own version numbers, while packages requiring the original package continue to work with your fork because it replaces the original package.

This is also useful for packages that contain sub-packages, for example the main symfony/symfony package contains all the Symfony Components which are also available as individual packages. If you require the main package it will automatically fulfill any requirement of one of the individual components, since it replaces them.

Caution is advised when using replace for the sub-package purpose explained above. You should then typically only replace using self.version as a version constraint, to make sure the main package only replaces the sub-packages of that exact version, and not any other version, which would be incorrect.

provide#
Map of packages that are provided by this package. This is mostly useful for implementations of common interfaces. A package could depend on some virtual package e.g. psr/log-implementation, any library that implements this logger interface would list it in provide. Implementors can then be found on Packagist.org.

Using provide with the name of an actual package rather than a virtual one implies that the code of that package is also shipped, in which case replace is generally a better choice. A common convention for packages providing an interface and relying on other packages to provide an implementation (for instance the PSR interfaces) is to use a -implementation suffix for the name of the virtual package corresponding to the interface package.

The issue is this is not compatible with Drupal 11.5 or 12, where you can actually install the new Toolbar contrib module. So it needs to be removed when your module installs with those core versions. I'll make an MR with the change using the "provide" key which reads like the correct option to me.

matthand’s picture

Assigned: Unassigned » matthand
Status: Active » Needs review

@dydave MR is ready for review with all green checks. Switching to a less than core constraint in the info yaml makes the "or" statements kind of awkward so I did the full range of compatible releases. Happy to change this if you'd like a different constraint strategy.

I went with the "provide" key but if you want the "replace" lmk and I'll swap it out.

Here's the logic regarding the version constraint if you want to settle on different numbers:

  • Drupal 10.6.x and 11.3.x do NOT have the "replace" key workaround in core for "drupal/toolbar"
  • Drupal 11.4.x has the workaround for "drupal/toolbar" in core itself
  • Drupal 11.5.x and 12.x can install "drupal/toolbar" from contrib and the workaround for "drupal/toolbar" will break the install
dydave’s picture

Status: Needs review » Needs work

Thanks Matt (@matthand) for the speedy reply and merge request!

I don't think we need to change the core_version_requirements. We should probably only keep your change to the composer.json.

This is our plan for the branches:
3.x: ^9.5 || ^10 || ^11
Will stay this way as the next LTS branch and use the Drupal core Toolbar module.
Installing 3.x will never install the contrib Toolbar module.

4.x (to be created): ^11.5 || ^12
Will be the new development branch and use the contrib Toolbar module.
See #3565206-27: [Meta] Roadplan for Admin Toolbar 3.6.x and 4.x

As you can see there is a breaking change with a major version of the Admin Toolbar module and so we should be able to have different versions for the composer.json.

If that's fine with you, could you please revert the changes to the info.yml file in the merge request?
Would you see any potential problems or conflicts with this added provide property if we had an overlap over versions above 11.5?

Otherwise, this seems to be the right way to go to mitigate this issue. 👌
I wonder if other deprecated modules have used similar strategies, such as the ban, history, shortcut, etc... 🤔

Thanks again for your great help! 🙏

dydave’s picture

Did a search locally in the vendor folder for "provide": and found several occurrences, such as:
vendor/guzzlehttp/guzzle/composer.json

    "provide": {
        "psr/http-client-implementation": "1.0"
    },

So in "theory" this solution "should" work... although I have never really tested this before. 🤞😅

dydave’s picture

Assigned: matthand » Unassigned
Status: Needs work » Needs review

OK, I've made the change to the MR. 👌

Back to Needs review. 🤞

Thanks!

matthand’s picture

Version: 3.6.3 » 3.x-dev
Status: Needs review » Reviewed & tested by the community
StatusFileSize
new77.6 KB
new67.42 KB
new76.88 KB

@dydave That version strategy works great! I was wrong that toolbar was removed from Drupal Core 11.5 Beta. It's only deprecated, which is what I should have expected. I was thrown off assuming that the core infrastructure had a good cause to be injecting the contrib module dependency into your composer.json... but NOPE! It's just an obvious mistake.

Tested the MR on Drupal 11.5.0-beta1 (Standard profile). Admin Toolbar installs and works, with no JS or watchdog errors. Screenshots attached. Standard installs the core Navigation module, which hides the classic toolbar. I switched back to it with:

drush pmu navigation -y
drush en toolbar admin_toolbar admin_toolbar_tools -y
drush cr
matthand’s picture

@dydave Tested MR on Drupal 11.3.19 as well and it works! Screenshots attached. Hope that's enough testing? I don't have much need for Drupal 10 anymore but this fix should work there as well.

dydave’s picture

Fantastic! Thanks a lot Matt (@matthand)! 🤩

I'm wrapping up changes for another ticket and should be able to get this one merged in very soon.

Thanks again for all the help and efforts testing and confirming the changes would help mitigating the issue! 🙏