Problem/Motivation
2.x currently declares core_version_requirement: ^10.1 || ^11, a single unbroken range spanning Drupal 10.1 through 11.x.
Starting with Drupal 11.4, core's http_kernel.basic service (Symfony\Component\HttpKernel\HttpKernel) changed its RequestStack constructor argument from Drupal's real @request_stack service to null (see the comment on that service definition in core.services.yml). Symfony's raw HttpKernel then keeps its own private, internal RequestStack for push()/pop(), separate from Drupal's request_stack service.
RequestSubscriber::onRequest() dispatches purl's stripped-prefix subrequest directly against the raw kernel ($event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST)), bypassing DrupalKernel::preHandle()/KernelPreHandle entirely. On Drupal 11.4+ this makes the subrequest invisible to Drupal's request_stack service for its whole lifecycle, so \Drupal::routeMatch(), \Drupal::request(), and CurrentRouteMatch resolve to the wrong request (or a null route) while purl's subrequest controller executes (see #3608029 for full symptoms/fix).
None of this occurs on 10.1–11.3, where http_kernel.basic still uses Drupal's real request_stack, so purl's existing 2.x subrequest code is correct there and needs no change. The actual fix in #3608029 requires Drupal core >=11.4 to ship cleanly (no runtime version branching), so 2.x should not receive that fix. Instead 2.x needs its core_version_requirement tightened so Composer never resolves it onto a broken 11.4+ site, plus a regression test proving 2.x remains correct on its own supported range.
Steps to reproduce
- Install purl 2.x on a site running Drupal core 11.4 or later.
- Configure any path-prefix modifier/provider.
- Visit a URL matching that prefix.
- Observe
Error: Call to a member function getOptions() on nullinPurlNodeContextRoutes::purlCheckNodeContext(), or any other code reading\Drupal::routeMatch()during the request resolving incorrectly.
Proposed resolution
- Update
purl.info.yml'score_version_requirementto exclude 11.4+ (e.g.^10.1 || >=11 <11.4). - Add
tests/src/Kernel/PurlSubrequestRequestStackTest.phpplus a companion minimal fixture moduletests/modules/purl_subrequest_test(a provider plugin exposing one fixed path-prefix modifier, a route, and a controller reporting\Drupal::request()->getPathInfo(),\Drupal::routeMatch()->getRouteName(), whethergetRouteObject()is null, and whether the current request equals the main request). The test performs a real in-process request through the prefixed path and asserts the subrequest's own controller sees itself — not the main request — as current. - No
RequestSubscribersource change is needed for this test to pass on 2.x.
Remaining tasks
- Confirm exact
core_version_requirementsyntax for the upper bound - Add the kernel test + fixture module (patch/MR to follow)
- Add/confirm a CI job pinned to Drupal 11.3 specifically (current
.gitlab-ci.ymltests 10.3/11.0, neither of which pins the 11.3→11.4 boundary this issue is about) - Release as a 2.x point release
User interface changes
None.
API changes
None — test and composer-constraint only.
Data model changes
None.
Issue fork purl-3608542
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
Comment #3
freelockMerge error is against the ancient "master" branch, merges fine into 8.x-1.x -- but shouldn't we have a 2.0.x branch?