Steps to reproduce

Drupal 9.3.2, with Layout Builder and Display Suite 8.x-3.13 enabled.
I've choose a DisplaySuite layout in a content form display.
Then, I cant' display content.

Problem/Motivation

Error: Call to undefined method Drupal\Core\Entity\Entity\EntityViewDisplay::isLayoutBuilderEnabled() in Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->isLayoutBuilderEnabled() (line 330 of core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php).
Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->isLayoutBuilderEnabled() (Line: 382)
Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->access() (Line: 362)
Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage->access() (Line: 37)
Drupal\layout_builder\Access\LayoutBuilderAccessCheck->access()
....

Proposed resolution

To work around the problem, not being a Drupal developer, I simply added the missing method such as:

namespace Drupal\Core\Entity\Entity;
...
class EntityViewDisplay extends EntityDisplayBase implements EntityViewDisplayInterface {
...
  public function isLayoutBuilderEnabled() {
	return \Drupal::moduleHandler()->moduleExists('layout_builder') ;
  }
...
}
CommentFileSizeAuthor
#7 3277728-7.patch792 byteseleonel

Issue fork drupal-3277728

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

marco5775 created an issue. See original summary.

larowlan’s picture

Status: Active » Postponed (maintainer needs more info)
Issue tags: +Bug Smash Initiative, +Needs steps to reproduce

Can you please provide steps to reproduce the issue starting from 'install drupal' - thanks

foxneil0912’s picture

I have this exact error only when i have Layout Field module enabled. When i disable it -> error is gone

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

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should 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.

flyke’s picture

I have a site using LayoutBuilder wich was working without problem.
I then added a new content type for which I needed and enabled DisplaySuite to select a layout for the teasers of that content type.

That resulted in the error:

The website encountered an unexpected error. Please try again later.
Error: Call to undefined method Drupal\Core\Entity\Entity\EntityViewDisplay::isLayoutBuilderEnabled() in Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->isLayoutBuilderEnabled() (line 335 of core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php).

This can be fixed by editing web/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php

And changing:

  /**
   * {@inheritdoc}
   */
  public function isLayoutBuilderEnabled() {
    return $this->getDisplay()->isLayoutBuilderEnabled();
  }

Into:

  /**
   * {@inheritdoc}
   */
  public function isLayoutBuilderEnabled() {
    $display = $this->getDisplay();
    if (!method_exists($display, 'isLayoutBuilderEnabled')) {
      return FALSE;
    }
    return $display->isLayoutBuilderEnabled();
  }

My layoutbuilder page which uses a content block that renders a view of teasers (for which I needed Display Suite) is still blank.
So I guess the issue of LayoutBuilder and Display Suite not working together at all still remains. This only fixes that specific error but its a step in the right direction.

tim.plunkett’s picture

Display Suite supposedly fixed this a couple years ago: #3054607: Layout builder incompatibility

eleonel’s picture

I have the same problem using Drupal 9.4.4, with Layout Builder and Layout builder library 8.x-1.0-beta3.

Steps: Save a node (with layout builder configured for the node's content type) and it may result in a white screen and in the logs you may found the same error as described on the description of this issue.

I tried to solve the issue by patching layout_library module https://www.drupal.org/project/layout_library/issues/3306517

But I'm still getting the error, so I plan to use the attached patch (based on #5)until we/someone implement a better solution.

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

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should 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

This a problem with layout builder or layout builder library?

Will need a test case for core to show this problem.

Will leave in PNMI for a few more months before closing if no follow up.

danielveza’s picture

Status: Postponed (maintainer needs more info) » Closed (cannot reproduce)

This has been PNMI for 6 months now with no further issue reports, and we have no steps to reproduce with just core. Closing this issue now, if someone can replicate this with just core feel free to reopen.

alex.bukach’s picture

Status: Closed (cannot reproduce) » Needs review

@DanielVeza we faced the issue recently on several projects, with the patch #7 having resolved it.

smustgrave’s picture

Version: 9.5.x-dev » 11.x-dev
Status: Needs review » Needs work

Steps to reproduce will still need to be added to issue summary.

Bugs require test coverage.

danielveza’s picture

Status: Needs work » Postponed (maintainer needs more info)

Could we please get a stacktrace as well?

kevinquillen’s picture

I am seeing a similar issue occur (Drupal 10.2.2). Occasionally when the cache clears (its not consistently happening), the entire site layout breaks and the PHP logs have this error:

Uncaught PHP Exception Error: "Call to undefined method Drupal\Core\Entity\Entity\EntityViewDisplay::isOverridable()" at /var/www/html/docroot/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php line 312

The error can persist through a few cache clears until it finally resolves itself. It should be noted we are using Memcache on Acquia, and this only happens in the production environment and never dev or stage.

The only LB related contributed modules we have are:

  • layout_builder_context
  • layout_builder_styles
  • layout_builder_iframe_modal
  • layout_builder_restrictions

This issue can then cascade down and cause other errors that are not real, like other core classes not existing (when they do). Once the cache is completely purged and rebuilt, its fine.

(unfortunately no stack trace logs for Acquia and the error is not visible on the site when it happens)

kevinquillen’s picture

Happened again today, even with the adapted patch above for isOverridable and isLayoutBuilderEnabled. Only this time, no logs. Again, only in prod. Running cron "corrected" the problem.

Our only other action here is removing Memcache on Acquia (Cloud Next) entirely and seeing if it persists.

kevinquillen’s picture

This issue is still happening at random, even with Memcache disabled.

Should this even be possible at that point in the code in Layout Builder?

Uncaught PHP Exception Error: "Call to undefined method Drupal\Core\Entity\Entity\EntityViewDisplay::isOverridable()" at /var/www/html/docroot/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php line 312

That method is defined as:

/**
 * {@inheritdoc}
 */
public function isOverridable() {
  $display = $this->getDisplay();

  return $this->getDisplay()->isOverridable();
}

getDisplay:

  /**
   * Gets the entity storing the defaults.
   *
   * @return \Drupal\layout_builder\Entity\LayoutEntityDisplayInterface
   *   The entity storing the defaults.
   */
  protected function getDisplay() {
    return $this->getSectionList();
  }

It says it should return an instance of LayoutEntityDisplayInterface, instead it returns an instance of EntityViewDisplay. Under what conditions could that happen? Trying to trace calls to isOverridable does not really produce much.

SectionStorage defines its context definition as an entity view display:

* @SectionStorage(
 *   id = "defaults",
 *   weight = 20,
 *   context_definitions = {
 *     "display" = @ContextDefinition("entity:entity_view_display"),
 *     "view_mode" = @ContextDefinition("string", default_value = "default"),
 *   },
 * )

This is where the trail runs cold for me. Does anyone know how or when EntityViewDisplay could be returned instead of an expected LayoutEntityDisplayInterface object that triggers the error?

tim.plunkett’s picture

What's the stack trace of the exception? Whatever it is, it's happening before layout_builder_entity_type_alter() has run, which shouldn't be possible.

danielveza’s picture

@kevinquillen This may be unrelated, but the code you've posted for DefaultsSectionStorage::isOverridable is different to cores. Is there a chance you have a patch that may be causing issues?

kevinquillen’s picture

Sorry, that was an error as I was trying a few things. Everything is removed now and back to

  /**
   * {@inheritdoc}
   */
  public function isOverridable() {
    return $this->getDisplay()->isOverridable();
  }
luke.leber’s picture

I may have some tangentially related info here. We recently found that due to how layout builder works (prior to Drupal 10.3), the accumulation of derived field blocks resulted in a single cache item in `cache_discovery` having a size of over 6mb.

This _may_ result in extreme performance problems for memcache users, because the default config won't store individual items over 1mb in size.

Just a theory, but such a large, virtually uncatchable, record could explain a lot of the "this should not be able to happen under normal circumstances" responses to this issue. Systems break down in wild ways when the underlying infrastructure doesn't behave as expected.

I'm curious if this happens in 10.3+ with most derived field blocks disabled so the block plugins CID falls below 1mb?

kevinquillen’s picture

I will add that we found this specific issue and error to happen far, far less with the application of this patch:

https://www.drupal.org/project/drupal/issues/3207813#comment-14380171

We then moved storage back from the database cache to memcache - but what Luke says in #20 is still true. We are still running Drupal 10.2.5.

I also found a way to replicate this issue:

  1. Clear the site cache
  2. Request random urls in the frontend of the site at the same time (literally within 1-3 seconds of cache clear initiation).

I was able to get the behavior 90% of the time, which is why this was so hard to track down in prod. It was once in a blue moon where the caches would clear as site traffic was happening at the same time to a degree that would cause this. The main issue is a deadlock on the cache_config table, which breaks (seems to break) plugin discovery and cache builds. But if this is the case I do not think this is specifically a Layout Builder issue but something in core as the above patch alludes to, it just happens to affect Layout Builder.

These may also be related:

  1. #2765271: Rationalize use of the 'discovery' cache bin, since it's stored in the limited size APCu by default
  2. #2832450: Multilingual config cached in "config" cache bin; quickly reaches APCu memory limits
  3. #3043330: Reduce the number of field blocks created for entities (possibly to zero)
kevinquillen’s picture

This thread seems close to the issue at hand:

https://www.drupal.org/project/shield/issues/3277210#comment-15083125

luke.leber’s picture

Potentially related issue on the same note as #22, albeit not in Middleware, but a different service constructor.

lan’s picture

Hello everyone,

I’ve been experiencing an issue related to Layout Builder on my site:

Error: Call to undefined method Drupal\Core\Entity\Entity\EntityViewDisplay::isLayoutBuilderEnabled() in Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->isLayoutBuilderEnabled() (line 341 of docroot/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php).

To address this, I applied the patch (in #7). However, after applying the patch, I am now encountering a new error (same as #16):
Error: Call to undefined method Drupal\Core\Entity\Entity\EntityViewDisplay::isOverridable() in Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->isOverridable() (line 318 of docroot/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php).

My Drupal version is 10.3.1 with Layout Builder enabled. My site only has one content type using Layout Builder and does not heavily rely on this module.

Has anyone else faced a similar issue after applying this patch? If so, how did you resolve it? Any insights or suggestions would be greatly appreciated.

Thanks in advance for your help!

smustgrave’s picture

Should this be reopened this?

smustgrave’s picture

Will say if this still happening lets put back into NW, but no follow up in 3 months could close out.

smustgrave’s picture

Wanted to bump 1 more time.

anthonylindsay’s picture

For what it's worth, we're seeing this issue now.
Happening on prod and dev environments, (mostly dev), not local.
Drupal 10.5.6
Redis
Layout builder and selected friends.

I _saw_ it on dev, and could not remedy it by any of

  1. cache clear
  2. run cron
  3. disable bigpipe

I got it to work once only by hitting update.php

But specifically clearing Redis made it work, and now, annoyingly I cannot recreate.

anthonylindsay’s picture

OK, after a few attempts, I can confirm that the method outlined in #21 works to replicate the problem, and flushing Redis rectifies it.

luke.leber’s picture

Status: Postponed (maintainer needs more info) » Needs work

We just had another incident this morning that started when the hosting provider was performing Memcached maintenance during which a memcached reboot happened.

As Memcached was rebooted, an out of memory error occurred and as a result, it seems like cache corruption happened.

luke.leber’s picture

More technical info...this is how to reproduce the symptom:

With layout builder enabled, execute:

$data = \Drupal::cache('discovery')->get('entity_type')->data;
$data['entity_view_display']->setClass('Drupal\Core\Entity\Entity\EntityViewDisplay');
\Drupal::cache('discovery')->set('entity_type', $data);

and observe that on the front-end all layout builder content disappears for anonymous users, and authenticated users face the exception detailed in the IS.

which should definitively prove that the cause of the symptom lies in the discovery cache bin.

The question is now how / why could the discovery cache bin be corrupted. Initial signs point to #3207813: ModuleHandler skips all hook implementations when invoked before the module files have been loaded, but I'm not convinced this is the only culprit, as our code-base has no inappropriate constructors about...

luke.leber’s picture

The next time this happens to anyone subscribing here, please run

drush php:eval "file_put_contents('/tmp/discovery-entity-type.txt', print_r(\Drupal::cache('discovery')->get('entity_type'), TRUE));"

and share the contents of your discovery cache. This will greatly aid in figuring out exactly what the original cause was (i.e. no entity type alter hooks running, some hooks not running, or some other kind of undefined behavior).

The above snippet should work on all cache backends (including memcache).

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

luke.leber changed the visibility of the branch 3277728-call-to-undefined to hidden.

luke.leber’s picture

Pushed a branch against 10.5.x for a possible production spy.

https://git.drupalcode.org/issue/drupal-3277728/-/compare/10.5.x...do-no...

luke.leber’s picture

Added acquia-specific production spy that reduces early bootstrap dependencies. All that's now needed from the container is the lock service, which is only dependent on the database service.

https://git.drupalcode.org/issue/drupal-3277728/-/compare/10.5.x...do-no...

To test beforehand...

  1. Create local env vars AH_SITE_GROUP=myapp + AH_SITE_ENVIRONMENT=myenv
  2. Create directory structure /mnt/files/myapp.myenv/files-private
  3. drush si minimal
  4. drush en layout_builder
  5. drush pm:uninstall page_cache
  6. Apply patch
  7. drush sql:query "truncate cache_discovery;"
  8. Comment out layout_builder_entity_type_alter hook
  9. Make a web request
  10. Observe uncaught exception '[[SPLUNK ALERT]] - Request abandoned due to possible cache corruption; see /mnt/files/myapp.myenv/files-private/3207813-debugging.txt for details.'
  11. Observe debugging information exists on disk
  12. Uncomment layout_builder_entity_type_alter hook
  13. Make a web request
  14. Observe application is now operational

Theoretically this should allow...

  1. Acquia environment agnosticism
  2. Required diagnostic info to be automatically collected the next time such a rare event occurs
  3. The application to automatically recover without manual intervention or extended disruption

to happen in a relatively unattended fashion...although it still may take some time for the problem to actually manifest.

luke.leber’s picture

Running

drush php:eval "file_put_contents('/tmp/discovery-entity-type.txt', print_r(\Drupal::cache('discovery')->get('entity_type'), TRUE));"

against a production Acquia environment while in a broken state yields an entity_view_display config object of...

            [entity_view_display] => Drupal\Core\Config\Entity\ConfigEntityType Object
                (
                    [id:protected] => entity_view_display
                    [class:protected] => Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay
                    [provider:protected] => core
                    [static_cache:protected] => 
                    [render_cache:protected] => 1
                    [persistent_cache:protected] => 1
                    [entity_keys:protected] => Array
                        (
                            [id] => id
                            [status] => status
                            [revision] => 
                            [bundle] => 
                            [langcode] => langcode
                            [default_langcode] => default_langcode
                            [revision_translation_affected] => revision_translation_affected
                            [uuid] => uuid
                        )

                    [originalClass:protected] => Drupal\Core\Entity\Entity\EntityViewDisplay
                    [handlers:protected] => Array
                        (
                            [access] => \Drupal\Core\Entity\Entity\Access\EntityViewDisplayAccessControlHandler
                            [storage] => Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplayStorage
                            [form] => Array
                                (
                                    [edit] => Drupal\layout_builder\Form\LayoutBuilderEntityViewDisplayForm
                                    [layout_builder] => Drupal\layout_builder\Form\DefaultsEntityForm
                                )

                            [inline_form] => \Drupal\inline_entity_form\Form\EntityInlineForm
                        )

                    [admin_permission:protected] => 
                    [collection_permission:protected] => 
                    [permission_granularity:protected] => entity_type
                    [links:protected] => Array
                        (
                        )

                    [bundle_entity_type:protected] => 
                    [bundle_of:protected] => 
                    [bundle_label:protected] => 
                    [base_table:protected] => 
                    [revision_data_table:protected] => 
                    [revision_table:protected] => 
                    [data_table:protected] => 
                    [internal:protected] => 
                    [translatable:protected] => 
                    [show_revision_ui:protected] => 
                    [label:protected] => Drupal\Core\StringTranslation\TranslatableMarkup Object
                        (
                            [string:protected] => Entity view display
                            [arguments:protected] => Array
                                (
                                )

                            [translatedMarkup:protected] => 
                            [options:protected] => Array
                                (
                                )

                            [stringTranslation:protected] => 
                        )

                    [label_collection:protected] => 
                    [label_singular:protected] => 
                    [label_plural:protected] => 
                    [label_count:protected] => Array
                        (
                        )

                    [uri_callback:protected] => 
                    [group:protected] => configuration
                    [group_label:protected] => Drupal\Core\StringTranslation\TranslatableMarkup Object
                        (
                            [string:protected] => Configuration
                            [arguments:protected] => Array
                                (
                                )

                            [translatedMarkup:protected] => 
                            [options:protected] => Array
                                (
                                    [context] => Entity type group
                                )

                            [stringTranslation:protected] => 
                        )

                    [field_ui_base_route:protected] => 
                    [common_reference_target:protected] => 
                    [list_cache_contexts:protected] => Array
                        (
                        )

                    [list_cache_tags:protected] => Array
                        (
                            [0] => config:entity_view_display_list
                        )

                    [constraints:protected] => Array
                        (
                            [ImmutableProperties] => Array
                                (
                                    [0] => id
                                    [1] => targetEntityType
                                    [2] => bundle
                                    [3] => mode
                                )

                        )

                    [additional:protected] => Array
                        (
                            [token_type] => entity_view_display
                        )

                    [_serviceIds:protected] => Array
                        (
                        )

                    [_entityStorages:protected] => Array
                        (
                        )

                    [stringTranslation:protected] => 
                    [config_prefix:protected] => 
                    [lookup_keys:protected] => Array
                        (
                            [0] => uuid
                        )

                    [config_export:protected] => Array
                        (
                            [0] => id
                            [1] => targetEntityType
                            [2] => bundle
                            [3] => mode
                            [4] => content
                            [5] => hidden
                        )

                    [mergedConfigExport:protected] => Array
                        (
                        )

                )

-- at least from the perspective of the SSH pod. There are caveats to this:

  1. The SSH pod only hits one of the memcache pods (which could have been non-corrupt possibly?)
  2. The SSH pod does not hit up the APCu cache on the web pods

So in other words, even after collecting this diagnostic info, it's still unclear which layer is being corrupted, even if from the perspective of the SSH pod, "everything is fine".

It doesn't look like anything short of the spy from #36 or #37 will be able to shine any more light on this.