New constants in \Drupal\Core\Theme\Registry are private but they are accessed with static::

Created on 20 June 2025, 3 days ago

Problem/Motivation

New constants in \Drupal\Core\Theme\Registry are private but they are accessed with static:: and this causes problems in 11.2.0 for the Twig UI module.

The website encountered an unexpected error. Try again later.

Error: Undefined constant Drupal\twig_ui\Theme\RegistryDecorator::PREPROCESS_INVOKES in Drupal\Core\Theme\Registry->build() (line 427 of core/lib/Drupal/Core/Theme/Registry.php).
Drupal\twig_ui\Theme\RegistryDecorator->build() (Line: 305)
Drupal\Core\Theme\Registry->get() (Line: 90)
Drupal\Core\Utility\ThemeRegistry->initializeRegistry() (Line: 71)
Drupal\Core\Utility\ThemeRegistry->__construct('theme_registry:runtime:olivero', Object, Object, Array, 1) (Line: 347)
Drupal\Core\Theme\Registry->getRuntime() (Line: 146)
Drupal\Core\Theme\ThemeManager->render(Array, Array) (Line: 493)
Drupal\Core\Render\Renderer->doRender(Array, Object) (Line: 506)
Drupal\Core\Render\Renderer->doRender(Array, Object) (Line: 223)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 623)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 131)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) (Line: 246)
Symfony\Component\EventDispatcher\EventDispatcher::Symfony\Component\EventDispatcher\{closure}(Object, 'kernel.view', Object) (Line: 206)
Symfony\Component\EventDispatcher\EventDispatcher->callListeners(Array, 'kernel.view', Object) (Line: 56)
Symfony\Component\EventDispatcher\EventDispatcher->dispatch(Object, 'kernel.view') (Line: 188)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 53)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 116)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 90)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 53)
Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 715)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Steps to reproduce

Install 11.2.0
Install twig_ui module
Clear cache and visit site

Proposed resolution

Use self:: instead.

Remaining tasks

User interface changes

None

Introduced terminology

N/a

API changes

None

Data model changes

None

Release notes snippet

N/a

πŸ› Bug report
Status

Active

Version

11.0 πŸ”₯

Component

theme system

Created by

πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

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

Merge Requests

Comments & Activities

  • Issue created by @alexpott
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ
  • Merge request !12427Fix constant access β†’ (Open) created by nicxvan
  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    Created the mr so I could review.

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    Is it better to just remove private?

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    Just noting @larowlan wanted them private originally, just curious if we should re evaluate here or if self is enough.

  • Pipeline finished with Failed
    3 days ago
    Total: 2067s
    #527469
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    Imo leave them as private - I've added a PHPStan rule that covers this situation. It's just a mistake to access private constants with static.

  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    As the methods that use the constants are protected shouldn't the constants also be protected? Or are we saying you shouldn't actually be overriding those methods?

  • Pipeline finished with Failed
    3 days ago
    Total: 517s
    #527499
  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    That failure might be real, I have rerun it 3 or 4 times.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    The failure has nothing to do with this change - it is one of the frontend changes from today.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    πŸ› Fix AssetAggregationAcrossPagesTest Active is the fix for the testing issue on 11.x

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ
  • πŸ‡¬πŸ‡§United Kingdom catch

    Looks like the idea behind making them private was because they might be temporary and be removed later, I think the MR here is fine for a quick fix, we can re-evaluate the constants themselves later.

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    I saw remarks elsewhere that some other recent commit might have added instability to the functional JS tests, so I queued it again.

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    The one that Alex posted is the test that was failing, this has not been rebased so it won't pass tests.

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    Also do we have a link to the other constants where they got added? I am only familiar with the registry ones but there are other constants in the mr.

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    The failure is to do with asset aggregation in Umami:

     Time: 03:16.817, Memory: 10.00 MB
    452
        
    453
        Asset Aggregation Across Pages (Drupal\Tests\demo_umami\FunctionalJavascript\AssetAggregationAcrossPages)
    454
         βœ” Front and recipes pages
    455
         βœ” Front and recipes pages authenticated
    456
         ✘ Front and recipes pages editor
    457
           ┐
    458
           β”œ Asserting ScriptBytes 335003 is greater or equal to 335137 and is smaller or equal to 336137
    459
           β”œ Failed asserting that 335003 ( is equal to 335137 or is greater than 335137 ) and ( is equal to 336137 or is less than 336137 ).
    460
      
    466
        FAILURES!
    467
        Tests: 3, Assertions: 29, Failures: 1, PHPUnit Deprecations: 8.

    So if that was the exact fail as before or after, we might worry. But I just checked and requeued the dailies, and they're also full of functional JS fails.

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    Sorry, crossposted with the above.

  • Pipeline finished with Failed
    3 days ago
    Total: 218s
    #527621
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    I think this is fine as a hotfix; we can file followups if we want to discuss further or change other constants.

    Saving issue credits; hopefully the rebased pipeline will be done by then.

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    For some reason now it's not triggering the later stages of the pipeline.

  • Pipeline finished with Failed
    3 days ago
    #527643
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    OK same issue as with the automated pipeline:

    ???

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    (and yes I am logged in)

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    I see that too, I am also logged in. Might be worth asking in infra.

  • Merge request !12431Resolve #3531412 "Tesr pupeline" β†’ (Open) created by nicxvan
  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    I created a new branch from this one too trigger a fresh pipeline to see if that works.

    Unfortunately I had typos in the title lol.

  • Pipeline finished with Success
    3 days ago
    Total: 392s
    #527662
    • xjm β†’ committed 403d53b2 on 11.x
      Issue #3531412 by alexpott, xjm, nicxvan, longwave, catch: New constants...
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    I did leave a message about it in #gitlab, yeah.

    Committed the results from the helpful tesr-pupeline branch 🀣 to 11.x.

    It doesn't cherry-pick cleanly to 11.2.x in core/lib/Drupal/Core/Theme/Registry.php, but we should make a separate version without the PHPStan rule addition anyway.

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    I did it from my phone lol.

  • πŸ‡¬πŸ‡§United Kingdom catch

    Pipeline weirdness might be fixed by giving yourself push access to the branch, I think I've had the same thing happen.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    alexpott β†’ changed the visibility of the branch 3531412-tesr-pupeline to hidden.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    alexpott β†’ changed the visibility of the branch 3531412-new-constants-in to hidden.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    I've cherry-picked the 11.x commit to the 11.2.x and resolved conflicts and backed out the PHPStan change.

    I ran vendor/bin/phpstan analyse -c core/phpstan.neon.dist core/lib/Drupal/Core/Theme/Registry.php --level=2 and confirmed that the constant issue is fixed on 11.2.x too.

  • Pipeline finished with Success
    2 days ago
    Total: 4777s
    #527893
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    Looks like it was these lines that were added in 11.x and prevented the cherry-pick, so it's a good thing we added the rule to HEAD at least:

    -      $cache[static::GLOBAL_PREPROCESS] = $this->collectModulePreprocess($cache, 'preprocess');
    +      $cache[self::GLOBAL_PREPROCESS] = $this->collectModulePreprocess($cache, 'preprocess');

    We should possibly backport the rule itself to 10.6.x as well.

  • πŸ‡ΊπŸ‡ΈUnited States xjm
    • xjm β†’ committed f3bb2ebd on 11.2.x
      Issue #3531412 by alexpott, xjm, nicxvan, catch, longwave: New constants...
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    Also checked the file as per #35. I probably should have run a full scan, but this is, after all, a hotfix. That is also why I am not requiring followups before commit. Committed to 11.2.x. Thanks!

    Setting NW for the followups.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    FWIW now we have the PHPStan rule in place, I think private constants are fine. In this case the constant is for an implementation detail of the code in \Drupal\Core\Theme\Registry - using a private constant means that anything that extends it should not rely on this implementation detail - which feels like fine architectural decision to me. I think we should only open a follow-up if we have an architectural reason to allow classes that extend \Drupal\Core\Theme\Registry access to the constant. For Twig UI this is not necessary at all. Somewhat sadly the 8.x-3.x version of Bootstrap hit this problem a couple of weeks ago but fixed it incorrectly in the Bootstrap theme rather than opening a core issue - see πŸ› Undefined constant Drupal\bootstrap\Plugin\Alter\ThemeRegistry::PREPROCESS_INVOKES in Drupal\Core\Theme\Registry->postProcessExtension() Active - I will open an issue against Bootstrap to revert that change once we have released the hotfix.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    Ah the bootstrap fix is yet to be merged. Another reason to get this fix released ASAP as we now have 2 confirmed cases in contrib and Bootstrap 8.x-3.x has about 50,000 users β†’ .

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    My two cents is if we are worried about people resulting in it we should have just used the array value.

    If we want them to be constants for consistency then they should be marked internal.

    Just because we don't know why someone would want to use it doesn't mean we should preclude it.

    This issue is an example of why, if they had not been private I don't think this issue would have existed in the first place right?

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    @nicxvan if they were not private yeah no issue... but the issue is not caused by the code in modules trying to use the constant. It is caused the late static binding... see https://3v4l.org/MDU2P

    I think we now have static analysis checking then it is fine to have private constants but before I'd agree that it is very easy to make a mistake.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ
Production build 0.71.5 2024