Hello,

When I do a cache rebuild I get an error called

Warning: Invalid argument supplied for foreach() in Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator->getDerivatives() (line 102 of core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php).
Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator->getDerivatives(Array) (Line: 87)
Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator->getDefinitions() (Line: 283)
Drupal\Core\Plugin\DefaultPluginManager->findDefinitions() (Line: 174)
Drupal\Core\Plugin\DefaultPluginManager->getDefinitions() (Line: 181)
Drupal\Core\Menu\LocalTaskManager->getDefinitions() (Line: 206)
Drupal\Core\Menu\LocalTaskManager->getLocalTasksForRoute('system.performance_settings') (Line: 290)
Drupal\Core\Menu\LocalTaskManager->getTasksBuild('system.performance_settings', Object) (Line: 358)
Drupal\Core\Menu\LocalTaskManager->getLocalTasks('system.performance_settings', 0) (Line: 94)
Drupal\Core\Menu\Plugin\Block\LocalTasksBlock->build() (Line: 203)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func('Drupal\block\BlockViewBuilder::preRender', Array) (Line: 376)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 448)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 490)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 47)
__TwigTemplate_f8a17f041581af9829850fd45db45c2b69d8b3a60b80408d416da5d23dbccb61->doDisplay(Array, Array) (Line: 432)
Twig_Template->displayWithErrorHandling(Array, Array) (Line: 403)
Twig_Template->display(Array) (Line: 411)
Twig_Template->render(Array) (Line: 64)
twig_render_template('core/themes/seven/templates/page.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('page', Array) (Line: 435)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 490)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 90)
__TwigTemplate_be8c7bbb9c824f2826368d7c8da984c6279779db72a67fd8056a00bb23b816f2->doDisplay(Array, Array) (Line: 432)
Twig_Template->displayWithErrorHandling(Array, Array) (Line: 403)
Twig_Template->display(Array) (Line: 411)
Twig_Template->render(Array) (Line: 64)
twig_render_template('core/themes/classy/templates/layout/html.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('html', Array) (Line: 435)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 147)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 574)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 148)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 149)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 64)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 656)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

It looks like it gets an empty object into a foreach loop. I fixed it with an empty check in the core, attached is the patch.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

johannijdam created an issue. See original summary.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Rajab Natshah’s picture

Do we have any updated about this issue?

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

renatog’s picture

Status: Needs review » Reviewed & tested by the community

I applied the patch and works good for me.

Good Work and Good Weekend.

Best,

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
@@ -99,14 +99,16 @@ protected function getDerivatives(array $base_plugin_definitions) {
         $derivative_definitions = $deriver->getDerivativeDefinitions($plugin_definition);
-        foreach ($derivative_definitions as $derivative_id => $derivative_definition) {
-          $plugin_id = $this->encodePluginId($base_plugin_id, $derivative_id);
-          // Use this definition as defaults if a plugin already defined
-          // itself as this derivative.
-          if ($derivative_id && isset($base_plugin_definitions[$plugin_id])) {
-            $derivative_definition = $this->mergeDerivativeDefinition($base_plugin_definitions[$plugin_id], $derivative_definition);
+        if(!empty($derivative_definitions)) {

It should not be necessary to check the emptiness here.

According to the docs in \Drupal\Component\Plugin\Derivative\DeriverInterface::getDerivativeDefinitions() (see below) $derivative_definitions should always be an array. We need to work out why it is not. What are the steps to reproduce the problem? What contrib modules are installed?

  /**
   * Gets the definition of all derivatives of a base plugin.
   *
   * @param array $base_plugin_definition
   *   The definition array of the base plugin.
   * @return array
   *   An array of full derivative definitions keyed on derivative id.
   *
   * @see getDerivativeDefinition()
   */
  public function getDerivativeDefinitions($base_plugin_definition);
Dinesh18’s picture

Status: Needs work » Needs review
FileSize
1.92 KB

$derivative_definitions is an array as per the documentation. I have reviewed the patch file and it seems,which returns an array called
$derivative_definitions from $deriver->getDerivativeDefinitions($plugin_definition);
We have used foreach for derivative_definitions to look for each definition.

Here is the interdiff which removes the if(!empty($derivative_definitions))

borisson_’s picture

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

#7 is just an interdiff, we need to have the patch as well, so maintainers don't need to apply both files.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Ben Coleman’s picture

Well, all the #7 interdiff does is revert back to the pre-patch state. Might as well just say don't use the patch.

We're running into the same problem on a Drupal 8.6 site, every time a node is changed via the UI.

gngn’s picture

I agree with alexpott (#6) and Dinesh18 (#7) that

According to the docs in \Drupal\Component\Plugin\Derivative\DeriverInterface::getDerivativeDefinitions() $derivative_definitions should always be an array.

but not with their conclusion

It should not be necessary to check the emptiness here.

Some modules (e.g.older version of ldap) fail to return an array (at least an empty one).

So in order to need to "work out why it is not" I think it would be better to test if $derivative_definitions is an array (an empty one is OK in foreach) and may be log a warning containing $base_plugin_id.
This way we know which module is responsible and can take action (and get rid of the PHP warning).

Patch attached (maybe we need dependency injection to use the logger?)

collinhaines’s picture

Had the same issue where this error was appearing after a cache clearing/rebuilding. Applied the patch in #11 and the error has not appeared since.

renatog’s picture

Status: Needs review » Reviewed & tested by the community

I agree with @collinhaimes

Also works good for me

+1 to it

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
@@ -99,14 +99,23 @@ protected function getDerivatives(array $base_plugin_definitions) {
+          // log warning about plugin uncorrectly implementing getDerivativeDefinitions()
+          \Drupal::logger('plugin discovery')->warning(
+            'getDerivativeDefinitions() does not return an array for plugin "@plugin".',
+            ['@plugin' => $base_plugin_id]
+          );

I think a trigger_error(E_USER_WARNING) is appropriate here. And let that do the logging. Then we don't have a call out to a service in the a component library.

Bring on strict types and return types in PHP7!

alexpott’s picture

Also tbh we are replacing a warning with a warning so /shrug - is this really worth it? Make for the extra info but still.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

DuneBL’s picture

Just to say that this log help me to debug a stupid error (forgot to return the famous array).
Working well... missing DI

raman.b’s picture

Version: 8.9.x-dev » 9.1.x-dev
Status: Needs work » Needs review
FileSize
1.14 KB
2.21 KB

Not sure how relevant this is. But adding patch to use trigger_error as per #14.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

borisson_’s picture

Status: Needs review » Needs work

Also tbh we are replacing a warning with a warning so /shrug - is this really worth it? Make for the extra info but still.

This is a really good question that is hard to answer, I think the more specific error here is better, so I'd give this a +1

+++ b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
@@ -99,14 +99,23 @@ protected function getDerivatives(array $base_plugin_definitions) {
+          // log warning about plugin uncorrectly implementing getDerivativeDefinitions()

This comment goes over 80 chars wide, should be reflowed. It also probably needs to start with a capital letter.

Spokje’s picture

Besides the comment issue mention by @borisson_ in #24 core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php also changes from 644 to 755 and that displeases TestBot:

Checking core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php

check failed: file core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php should be 644 not 755
PHPCS: core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php passed
priya.chat’s picture

Hi All, thanks for looking into this issue. I am also trying to help here.
I have made few changes in patch #11, as added one more check for array count.

Also, as suggested by @borisson_ in #24 , I have corrected the comment line. this may help.

pooja saraah’s picture

Fixed Failed Commands on #26
Attached interdiff

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Bug Smash Initiative, +Needs issue summary update, +Needs tests, +Needs Review Queue Initiative

This issue is being reviewed by the kind folks in Slack, #need-reveiw-queue. We are working to keep the size of Needs Review queue [2700+ issues] to around 200, following Review a patch or merge require as a guide.

Moving back to NW for an issue summary update as the solution appears to be add a more detailed log which isn't mentioned in the IS.

Also think this will need a test case

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.