Problem/Motivation
Original report:
I migrated content from my D7 site to a D8 clean install following the handbook. I did not install any other module except from the one already present in the clean install.
If I enable layout builder the sites goes blank (front and admin), giving the following error:
The website encountered an unexpected error. Please try again later.
Error: Call to a member function getLabel() on null in Drupal\layout_builder\Plugin\Derivative\FieldBlockDeriver->getDerivativeDefinitions() (line 111 of core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php).The FieldBlockDeriver iterates over the results of \Drupal\Core\Entity\EntityFieldManagerInterface::getFieldMap() and later retrieves corresponding definitions via \Drupal\Core\Entity\EntityFieldManagerInterface::getFieldDefinitions().
Every field listed in the field map should have a valid field definition, even more so because they are returned by the same service.
However, these two lists can get out of sync with each other under certain circumstances (migrations, bundle creation).
Fields, base fields, and extra fields are all cached using the entity_field_info tag as well as the entity_types tag.
The field map info is only cached by the entity_types tag.
The ::clearCachedFieldDefinitions() method in this service only clears the entity_field_info tag.
Additionally, while \Drupal\Core\Entity\EntityBundleListener::onBundleDelete() calls the ::clearCachedFieldDefinitions() method,
\Drupal\Core\Entity\EntityBundleListener::onBundleCreate() does not.
Proposed resolution
Cache the field map with the entity_field_info tag, to match everything else in this service, as well as the cache clearing method.
Add a call to \Drupal\Core\Entity\EntityFieldManagerInterface::clearCachedFieldDefinitions() in \Drupal\Core\Entity\EntityBundleListener::onBundleCreate().
Remaining tasks
N/A
User interface changes
N/A
API changes
N/A
Data model changes
N/A
Comments
Comment #2
tedbowInteresting problem:
Looking at the code:
It seems like difference in what is being returned by
\Drupal\Core\Entity\EntityFieldManagerInterface::getFieldMap()and
\Drupal\Core\Entity\EntityFieldManagerInterface::getFieldDefinitions()$this->entityFieldManager->getFieldDefinitions($entity_type_id, $bundle)[$field_name]Should work because
getFieldMapshould not return a field name for the bundle that doesn't exist on the bundle and that you can't get a definition for by callinggetFieldDefinitions()So maybe it is problem with
\Drupal\Core\Entity\EntityFieldManager()Comment #3
tim.plunkettInteresting. I just was hitting issues with EntityFieldManager on #2959132: Taxonomy pages crash with layout_builder enabled. Could be related?
The main thing was that the cache was not being cleared correctly.
Comment #5
vmilic commentedThank you for pointing me in the right direction!
Seems that a wrong field mapping for a bundle was causing the issue, due to the migration process.
I found the issue #2916266: How to fix "non-existent config entity name returned by FieldStorageConfigInterface::getBundles()" ; applying the solution in comment #8 solved the problem.
Thank you!
Comment #6
tim.plunkettComment #7
tim.plunkettAssigning to @phenaproxima for help debugging the migrate test fails.
Comment #8
phenaproximaThat was a tricky one, but I think I know what's causing this. The failing tests do not actually install the node entity tables, and the new cache tag causes Content Translation to attempt to create the content_translation_source field on the node data table. But since the table does not exist, it's failing.
Let's see what the attached patch does.
Comment #9
phenaproximaAlso, 8.7.x, people!
Comment #10
tim.plunkettThanks for the help @phenaproxima!
Here's a generic test for this.
The FAIL-TOTALLY patch is the interdiff.
Also attached are two other FAIL patches, to prove that both the change in EntityBundleListener and EntityFieldManager are needed in conjunction.
Comment #11
tim.plunkettFixed an extra blank line, here's the interdiff
Comment #12
tim.plunkettUpdated the IS.
Comment #15
tim.plunkettClosing #2926139: EntityFieldManager's field map not invalidated as promised as a duplicate as this issue is more complete, but crediting those who worked over there on a fix.
Comment #16
berdirIf => When?
Until now, I guess that didn't happen, but afaik comments should avoid refering to how things used to work, because someone reading that likely doesn't have that context.
Also, reading this makes me wonder just how closely this is related to #2599228: Programmatically created translatable content type returns SQL error on content creation and whether that is adding workarounds when the real problem is actually this?
Comment #17
tim.plunkett100% agreed on the "write comments for how things are".
In fact, I don't think a comment is needed here at all.
Seeing that in a test doesn't make me question why the second line is there. It fits right in. And if more clarity is needed, there is git blame.
Comment #18
berdirNice.
We discussed in Slack whether or not it would make sense that the added call to clearCachedFieldDefinitions() needs a comment or not, @tim.plunkett argued that the identical call in onBundleDelete() doesn't have one either, which isn't wrong :)
Tim also confirmed that this indeed seems to fix the related issue I referenced above, which is a 3 year old major bug with 57 followers and this fix is way simpler than the workaround that was done there.
Comment #19
psf_ commentedHi, the patch in #17 don't fix my use case described in "Programmatically created translatable content type returns SQL error on content creation".
While install I get:
Going to the error page the installation continue, when finish, I do a
drush entity-updatesand crash with:Comment #20
berdirNeither did the patch over there from what I understood.
The other issue isn't closed as a duplicate, just postponed, because it makes sense to commit this first and then revisit if and what still needs to be done there.
Comment #21
psf_ commentedYes, I misunderstand. We'll stop core update while this issues are open.
Other possibility is that the problem came from "default content" module, it's uncanny but possible.
Thanks @Berdir :)
Comment #22
wim leers@tim.plunkett++
@Berdir++
Comment #23
alexpottCommitted and pushed d3784a1300 to 8.7.x and e2ffcb5e03 to 8.6.x. Thanks!