Warning: Undefined array key "function" in Drupal\Core\Utility\Error::getLastCaller() (line 130 of core/lib/Drupal/Core/Utility/Error.php).

Created on 26 June 2023, about 1 year ago
Updated 16 February 2024, 4 months ago

Problem

Sometimes I see this message on screen: "Warning: Undefined array key "function" in Drupal\Core\Utility\Error::getLastCaller() (line 130 of core/lib/Drupal/Core/Utility/Error.php). "

Steps to reproduce

See #11

Proposition

Need to add checking on key existing.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Base 

Last updated about 1 hour ago

Created by

🇺🇦Ukraine r_cheh

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

Merge Requests

Comments & Activities

  • Issue created by @r_cheh
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update about 1 year ago
    30,341 pass
  • Status changed to Needs review about 1 year ago
  • 🇺🇸United States cilefen

    Interesting! Is there a reliable list of steps to reproduce this?

  • Status changed to Needs work about 1 year ago
  • 🇺🇸United States smustgrave

    How we have handled other tickets like this is to investigate why the array key wasn't set when it was expected. Adding an isset or empty check may just be masking a larger issue.

  • 🇺🇸United States cilefen

    True, but this is in a backtrace, derived from $exception->getTrace(), so it's something on the PHP side I think, not something that any Drupal code could be doing "wrong". Possibly we shouldn't even call getLastCaller if there isn't one.

  • 🇳🇿New Zealand quietone New Zealand

    Yesterday, I got the same error when playing around with drush generate and routes. Unfortunately, I have tried yesterday and today and I am not able to reproduce it. It is rather frustrating.

  • 🇳🇿New Zealand quietone New Zealand

    $ddev drush generate yml:routing generates this, test.routing.yml.

    test.example:
      path: '/test/example'
      defaults:
        _controller: '\Drupal\test\Controller\TestController::build'
        _title: 'Example'
      requirements:
        _permission: 'some permission'

    In the TestController return the wrong object

      public function  build() {
        return parent::formBuilder();
      }
    

    The results is WSOD

    The website encountered an unexpected error. Try again later.
    
    Symfony\Component\HttpKernel\Exception\ControllerDoesNotReturnResponseException: The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned an object of type Drupal\Core\Form\FormBuilder. in () (line 98 of core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php).
    
    Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 76)
    Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 59)
    Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 28)
    Drupal\Core\StackMiddleware\ContentLength->handle() (Line: 32)
    Drupal\big_pipe\StackMiddleware\ContentLength->handle() (Line: 106)
    Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
    Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 36)
    Drupal\Core\StackMiddleware\AjaxPageState->handle() (Line: 51)
    Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 711)
    Drupal\Core\DrupalKernel->handle() (Line: 19)
    

    and a warning

    Warning: Undefined array key "function" in Drupal\Core\Utility\Error::getLastCaller() (line 150 of /var/www/html/core/lib/Drupal/Core/Utility/Error.php)
    
    #0 /var/www/html/core/includes/bootstrap.inc(164): _drupal_error_handler_real()
    #1 /var/www/html/core/lib/Drupal/Core/Utility/Error.php(150): _drupal_error_handler()
    #2 /var/www/html/core/lib/Drupal/Core/Utility/Error.php(63): Drupal\Core\Utility\Error::getLastCaller()
    #3 /var/www/html/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php(84): Drupal\Core\Utility\Error::decodeException()
    #4 [internal function]: Drupal\Core\EventSubscriber\FinalExceptionSubscriber->onException()
    #5 /var/www/html/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func()
    #6 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(239): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch()
    #7 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(91): Symfony\Component\HttpKernel\HttpKernel->handleThrowable()
    #8 /var/www/html/core/lib/Drupal/Core/StackMiddleware/Session.php(59): Symfony\Component\HttpKernel\HttpKernel->handle()
    #9 /var/www/html/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
    #10 /var/www/html/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
    #11 /var/www/html/core/modules/big_pipe/src/StackMiddleware/ContentLength.php(32): Drupal\Core\StackMiddleware\ContentLength->handle()
    #12 /var/www/html/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\big_pipe\StackMiddleware\ContentLength->handle()
    #13 /var/www/html/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
    #14 /var/www/html/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
    #15 /var/www/html/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
    #16 /var/www/html/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
    #17 /var/www/html/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle()
    #18 /var/www/html/core/lib/Drupal/Core/DrupalKernel.php(711): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
    #19 /var/www/html/index.php(19): Drupal\Core\DrupalKernel->handle()
    #20 {main}

    And this is the $backtrace array

    (
        [0] => Array
            (
                [line] => 98
                [file] => /var/www/html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php
            )
    
        [1] => Array
            (
                [line] => 181
                [file] => /var/www/html/vendor/symfony/http-kernel/HttpKernel.php
            )
    
        [2] => Array
            (
                [file] => /var/www/html/vendor/symfony/http-kernel/HttpKernel.php
                [line] => 76
                [function] => handleRaw
                [class] => Symfony\Component\HttpKernel\HttpKernel
                [type] => ->
            )
    
        [3] => Array
            (
                [file] => /var/www/html/core/lib/Drupal/Core/StackMiddleware/Session.php
                [line] => 59
                [function] => handle
                [class] => Symfony\Component\HttpKernel\HttpKernel
                [type] => ->
            )
    
        [4] => Array
            (
                [file] => /var/www/html/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php
                [line] => 48
                [function] => handle
                [class] => Drupal\Core\StackMiddleware\Session
                [type] => ->
            )
    
        [5] => Array
            (
                [file] => /var/www/html/core/lib/Drupal/Core/StackMiddleware/ContentLength.php
                [line] => 28
                [function] => handle
                [class] => Drupal\Core\StackMiddleware\KernelPreHandle
                [type] => ->
            )
    
        [6] => Array
            (
                [file] => /var/www/html/core/modules/big_pipe/src/StackMiddleware/ContentLength.php
                [line] => 32
                [function] => handle
                [class] => Drupal\Core\StackMiddleware\ContentLength
                [type] => ->
            )
    
        [7] => Array
            (
                [file] => /var/www/html/core/modules/page_cache/src/StackMiddleware/PageCache.php
                [line] => 106
                [function] => handle
                [class] => Drupal\big_pipe\StackMiddleware\ContentLength
                [type] => ->
            )
    
        [8] => Array
            (
                [file] => /var/www/html/core/modules/page_cache/src/StackMiddleware/PageCache.php
                [line] => 85
                [function] => pass
                [class] => Drupal\page_cache\StackMiddleware\PageCache
                [type] => ->
            )
    
        [9] => Array
            (
                [file] => /var/www/html/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php
                [line] => 48
                [function] => handle
                [class] => Drupal\page_cache\StackMiddleware\PageCache
                [type] => ->
            )
    
        [10] => Array
            (
                [file] => /var/www/html/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php
                [line] => 51
                [function] => handle
                [class] => Drupal\Core\StackMiddleware\ReverseProxyMiddleware
                [type] => ->
            )
    
        [11] => Array
            (
                [file] => /var/www/html/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php
                [line] => 36
                [function] => handle
                [class] => Drupal\Core\StackMiddleware\NegotiationMiddleware
                [type] => ->
            )
    
        [12] => Array
            (
                [file] => /var/www/html/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php
                [line] => 51
                [function] => handle
                [class] => Drupal\Core\StackMiddleware\AjaxPageState
                [type] => ->
            )
    
        [13] => Array
            (
                [file] => /var/www/html/core/lib/Drupal/Core/DrupalKernel.php
                [line] => 711
                [function] => handle
                [class] => Drupal\Core\StackMiddleware\StackedHttpKernel
                [type] => ->
            )
    
        [14] => Array
            (
                [file] => /var/www/html/index.php
                [line] => 19
                [function] => handle
                [class] => Drupal\Core\DrupalKernel
                [type] => ->
            )
    
    )
  • First commit to issue fork.
  • Status changed to Needs review 5 months ago
  • 🇮🇳India shalini_jha

    Hello everyone
    I have followed all the steps mentioned in #11 and i am able to replicate this issue.
    $callback[1] key is not have function key for this condition.
    so this is trowing the warning , after checking isset condition for this it will skip this if condition for this so not showing the warning.
    please review . thanks

  • Status changed to RTBC 5 months ago
  • 🇩🇪Germany marcoliver Neuss, NRW, Germany

    Was able to reproduce the warning & the patch fixes the issue. Marking RTBC.

  • Status changed to Needs work 5 months ago
  • 🇺🇸United States smustgrave

    Needs test coverage.

    But still think we need to figure out why that value is empty vs just putting a isset check

  • Merge request !6299backtrace with no function → (Open) created by quietone
  • Status changed to Needs review 5 months ago
  • 🇳🇿New Zealand quietone New Zealand

    @shalini_jha, are you sure that the patch fixed the problem? The fail was in the 'else' of that 'if' block, not the 'if'.

    I created a test from my results in #11 and then made the fix. The error message in #11 is the same as the in Issue summary and the failure on the same line 130 in 9.5.x and 150 in 11.x.

  • Status changed to RTBC 5 months ago
  • 🇺🇸United States smustgrave

    That look great @quietone!

    Ran the test locally as I can't run the test-only feature

    Undefined array key "function"
     /var/www/html/vendor/symfony/phpunit-bridge/DeprecationErrorHandler.php:132
     /var/www/html/web/core/lib/Drupal/Core/Utility/Error.php:150
     /var/www/html/web/core/tests/Drupal/Tests/Core/Utility/ErrorTest.php:27
     /var/www/html/web/vendor/phpunit/phpunit/src/Framework/TestResult.php:728
     /var/www/html/web/vendor/phpunit/phpunit/src/Framework/TestSuite.php:684
     /var/www/html/web/vendor/phpunit/phpunit/src/Framework/TestSuite.php:684
     /var/www/html/web/vendor/phpunit/phpunit/src/Framework/TestSuite.php:684
     /var/www/html/web/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:651
     /var/www/html/vendor/phpunit/phpunit/src/TextUI/Command.php:144
     /var/www/html/vendor/phpunit/phpunit/src/TextUI/Command.php:97
    

    Which shows the coverage. This change seems good to mark now.

  • Status changed to Needs work 5 months ago
  • 🇬🇧United Kingdom longwave UK

    Coincidentally I ran into this one this week, it didn't bother me enough to file an issue but then it turns up in the RTBC queue.

    Made a suggestion to make the code slightly easier to read, otherwise this looks good to me.

  • First commit to issue fork.
  • Pipeline finished with Canceled
    5 months ago
    Total: 24s
    #90816
  • Pipeline finished with Success
    5 months ago
    Total: 520s
    #90817
  • 🇫🇷France DYdave

    This doesn't fully work though, I'm still seeing PHP warnings:

    Warning: Undefined array key "function" in Drupal\Core\Utility\Error::decodeException() (line 70 of core/lib/Drupal/Core/Utility/Error.php).
    Drupal\Core\Utility\Error::decodeException(Object) (Line: 69)
    Drupal\Core\EventSubscriber\ExceptionLoggingSubscriber->onError(Object) (Line: 118)
    Drupal\Core\EventSubscriber\ExceptionLoggingSubscriber->onException(Object, 'kernel.exception', Object)
    call_user_func(Array, Object, 'kernel.exception', Object) (Line: 111)
    Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.exception') (Line: 239)
    Symfony\Component\HttpKernel\HttpKernel->handleThrowable(Object, Object, 1) (Line: 91)
    Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
    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: 106)
    Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
    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: 36)
    Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
    Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 704)
    Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
    

    https://git.drupalcode.org/project/drupal/-/blob/a201c7006b4280be0ec65bb...

    With the changes from the MR, there may be cases where the 'function' key may never be returned by Drupal\Core\Utility\Error::getLastCaller, for exemple if $backtrace[1] is set but doesn't have a 'class' or 'function' key.
    Resulting in the warning above.

    See an example of a dpm of the backtrace :

    array:15 [▼
      0 => array:2 [▼
        "line" => 98
        "file" => "/var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php"
      ]
      1 => array:2 [▼
        "line" => 181
        "file" => "/var/www/html/vendor/symfony/http-kernel/HttpKernel.php"
      ]
      2 => array:5 [▼
        "file" => "/var/www/html/vendor/symfony/http-kernel/HttpKernel.php"
        "line" => 76
        "function" => "handleRaw"
        "class" => "Symfony\Component\HttpKernel\HttpKernel"
        "type" => "->"
      ]
      3 => array:5 [▶]
      4 => array:5 [▶]
    ...
    ]
    

    A fallback case could perhaps be added after the elseif, maybe something similar to the current else case?
    https://git.drupalcode.org/project/drupal/-/blob/a201c7006b4280be0ec65bb...

    Maybe the 'class' or 'function' keys could be pulled from $backtrace[2], if they can't be pulled from $backtrace[1]? (see backtrace above)

    Not sure if that's a case that needs to be covered by the method though ...

    This case corresponds to the following exception: (Controller returning NULL instead of a Response)
    Symfony\Component\HttpKernel\Exception\ControllerDoesNotReturnResponseException : The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned null. Did you forget to add a return statement somewhere in your controller? in (line 98 of /web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php).

    Any advice, guidance or suggestions on how to best handle this limit case, would be particularly appreciated.
    Thanks in advance !

  • Assigned to himanshu_jhaloya
  • Issue was unassigned.
  • Status changed to Needs review 4 months ago
  • 🇮🇳India himanshu_jhaloya Mandsaur

    Hi, I have followed all the steps mentioned in #11 and I can replicate this issue.
    so this is throwing the warning, I have added the patch
    please review. thanks

  • Status changed to Needs work 4 months ago
  • 🇺🇸United States smustgrave

    Patch appears to be the same as MR.

  • 🇩🇰Denmark ressa Copenhagen

    @himanshu_jhaloya: Manually attaching patches is being phased out, and you should create a patch (or update existing) and Merge Request with the Gitlab integration.

    DrupalCI and all patch testing will be turned off on July 1, 2024

Production build 0.69.0 2024