Problem/Motivation
If a default layout has a custom block placed and overridden layouts exist, deleting the custom block from the default can trigger
Error: Call to a member function getEntityTypeId() on null in Drupal\layout_builder\Plugin\Block\InlineBlock->build() (line 218 of core/modules/layout_builder/src/Plugin/Block/InlineBlock.php).
Steps to reproduce
- Add a custom block to a layout default
- Begin editing a layout override, do not save
- Remove the block from the default
- Attempt to continue editing the layout override
Proposed resolution
If a block can not be loaded, change \Drupal\layout_builder\Plugin\Block\InlineBlock
such that:
- a visual warning is shown to privileged users that the block is broken or missing, and
- log error.
Remaining tasks
- Review change request.
- Approve and merge.
User interface changes
N/A
API changes
\Drupal\layout_builder\Plugin\Block\InlineBlock::__construct
now requires $logger
to be passed.
Data model changes
N/A
Release notes snippet
If a default layout has a custom block placed and overridden layouts exist, deleting the custom block from the default can trigger an error in
InlineBlock->build()
. A user-friendly warning message is now displayed and logged.
Comment | File | Size | Author |
---|
Issue fork drupal-3049332
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
Comment #2
andyg5000Added link to class/error
Comment #3
andyg5000I'm including patches for 8.6.x so people can apply them to the current release if needed as well as the 8.8.x branch. Probably not the fix that will be chosen, but shows the issue and how to solve it. Cheers!
Comment #4
andyg5000Sorry these should be returning [] instead of FALSE;
Comment #5
mathew.oakes CreditAttribution: mathew.oakes commentedFWIW here's an 8.7 patch for the same flaw. These didnt apply for me.
Comment #6
bkosborneYes, I got this too. For some reason, the inline block was deleted but the reference to it is still on the page. No idea how that happened.
Comment #7
bkosborneComment #8
bkosborneHere's a minor change that adds logging (without dependency injection). This needs tests and properly injected logger, but I just needed this quickly.
Comment #9
GoZ CreditAttribution: GoZ at Iosan, Barbe-Rousse commentedKeeps it in needs review to let tests work.
Patch replace logger static call by injection.
Does someone can describe steps to reproduce please ? This will help to write tests.
Comment #11
GoZ CreditAttribution: GoZ at Iosan, Barbe-Rousse commentedReplace logger service by
logger.channel.layout_builder
Comment #12
bkosborneI reproduced this by manually deleting the inline block in the database. Somehow that happened on a production site, but I'm not sure how. Only thing I can think of at the moment is that maybe two people were modifying a layout at the same time and one person deleted the block while the other kept it in the layout?
Comment #13
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedIsn't this masking potential data loss issues by not failing hard and explicitly? The underlying problem is that somehow an inline block was deleted when it shouldn't have been. Figuring out the root cause of why should probably be the first step.
Having this fail silently with a log message seems a bit dangerous, given in all future tests, the system as a whole will continue to work.
Comment #14
wturrell CreditAttribution: wturrell as a volunteer commented(core 8.7.7) – I configured a layout for a content type using layout builder on dev, exported the config to Git, imported it to a production site I'm currently building (along with core.extension.yml to enable the layout_builder modules), cleared the cache, and:
- the nodes were showing both the layout builder content and the default 'manage display'-style fields simultaneously
- on clicking the 'Manage Layout' button in Manage Display, I got the InlineBlock.php:build() method getEntityTypeId() error above - NB: it's now line 223
I was able to disable layout builder, so I did that.
Then, I tried reimporting the dev synchronised config a second time.
Now the node displays as intended, but the error when trying to access the layout builder itself still persists.
Anyone else had this / suggest a solution or anything obvious I'm missing?
Comment #15
wturrell CreditAttribution: wturrell as a volunteer commented…now I've had time to test:
(a) the latest patch (#11) applies and fixes (bypasses) the problem ( @bkosborne / Goz - thanks for adding the logging )
(b) it was my own fault for forgetting during the process I'd actually created a custom block, which I hadn't exported (and of course blocks, along with taxonomies and menus, don't get synced).
re: #13, personally I find the patch preferable, given that it at least allows you to view the Layout Builder UI, and that says "Placeholder" where the block content would be, so you can see what's wrong (maybe there's a case for using CSS to make that more prominent).
Comment #17
tim.plunkettNW for tests
Comment #18
albertski CreditAttribution: albertski at Xeno Media, Inc. commentedThis is how I get the error:
- Created a page using Page Manager and Layout Builder (Required patch: #2960739)
- Add inline blocks to the page
- Exported config
- Pushed changes to production/staging
- Import config
- Navigate to the edit layout page and you will see the error (Because the block doesn't exist)
This patch fixed the issue for me.
Comment #20
energee CreditAttribution: energee as a volunteer and at EPAM Systems commentedConfirmed patch working on 8.9.1.
Comment #21
vsujeetkumar CreditAttribution: vsujeetkumar at Material for Drupal India Association commentedReroll patch needed as not apply on 9.1.x
Comment #22
vsujeetkumar CreditAttribution: vsujeetkumar at Material for Drupal India Association commentedReroll patch created, Please review.
Comment #23
geek-merlin@Sam152 #13:
> Having this fail silently with a log message seems a bit dangerous, given in all future tests, the system as a whole will continue to work.
I strongly agree with this. Rerolled the patch to output a visible error message rather than a silent log message.
Setting NR to trigger bot, but still needs tests.
Comment #24
geek-merlinNW for tests.
Comment #25
geek-merlinNope, #23 was the wrong patch. Here we go.
Comment #26
geek-merlinTested it manually, the last patch was missing the t(). Sorry for the noise.
Comment #27
geek-merlinTested manually and worksforme.
Note that, apart from the error message, the block is shown as "Placeholder for the 'Foo' block".
IMHO the best would be if we show the block in error-red with text "'Foo' block (broken)".
NW for deciding this & automated tests.
Comment #28
Rajab Natshah CreditAttribution: Rajab Natshah at Vardot commentedThank you for the patch
It's working with default content
Comment #29
bradallenfisher CreditAttribution: bradallenfisher commentedI can create this very easily without a cross env config sync.
I basically broke it within like 4 hours of playing with the builder. :) whoops.
Comment #30
bradallenfisher CreditAttribution: bradallenfisher commentedI applied the patch in #26 and it's working very nicely. Thank you for the patch. The error is obvious.
Comment #31
tim.plunkettLet's hope #29 is enough to write some tests from.
As currently documented, InlineBlock::getEntity() is always supposed to return a block. But
RevisionableStorageInterface::loadRevision()
can return a NULL, and this code doesn't account for it.So getEntity() needs to be adjusted to either:
Comment #32
tim.plunkettAha! I was able to reproduce with one key addition:
Step 4 is the key here. It's the tempstore that is storing the old block revision ID.
Now we can write tests for this.
Comment #33
tim.plunkettI still think the fix should shift to getEntity(), but in the meantime here's a test with the patch from #26.
I'm also not sure about the logger vs message part. Now that we have steps to reproduce, this isn't as mysterious as it was (and definitely not a data loss problem).
I think a middle ground would be to mimic Broken block by returning a render array with the broken message, and logging it.
Comment #38
tim.plunkettIn Slack, there was a discussion of the 3 options in the issue summary.
@jibran pointed to #3007424: Multiple usages of FieldPluginBase::getEntity do not check for NULL, leading to WSOD which is essentially the same problem.
So, conforming to that approach (aka #1 from the IS) but switching from a message to logging.
Comment #39
hudriThe same issue exists even without override layouts, when using configuration synchronization.
Steps to reproduce:
Comment #41
galactus86 CreditAttribution: galactus86 at Mediacurrent commentedApplied 3049332-inline-33-PASS.patch to Drupal 8.9.3 site. Overridden layout indeed had unsaved changes and a broken block ID.
Patch worked to get me past error message and able to edit and save page!
I have found similar types of issues with Layout Builder so will report back any additional blockers.
Comment #42
alexpottThe fix and test look great.
This needs to be the last argument and trigger a deprecation notice
like the $current_user argument... and then in D10 both with be required.EDIT: The reason $logger was not added last is because $current_user was optional in D8 - because it was added and triggered a deprecation notice. So we need to do the same for this.
Comment #43
VoodooSource CreditAttribution: VoodooSource as a volunteer commentedConfirmed Patch in #11 works on 8.9.6
Comment #44
tim.plunkettRestoring version
Comment #45
anmolgoyal74 CreditAttribution: anmolgoyal74 at OpenSense Labs for DrupalFit commentedI hope this is required here.
Comment #46
anmolgoyal74 CreditAttribution: anmolgoyal74 at OpenSense Labs for DrupalFit commentedComment #48
wmcmillian-coalmarch CreditAttribution: wmcmillian-coalmarch commentedRolled out #45 for Drupal 8.9
Comment #49
wmcmillian-coalmarch CreditAttribution: wmcmillian-coalmarch commentedWhoops... flipped around parameters to address #42
Comment #50
anmolgoyal74 CreditAttribution: anmolgoyal74 at OpenSense Labs for DrupalFit commentedComment #51
vsujeetkumar CreditAttribution: vsujeetkumar at Material for Drupal India Association commentedFixing tests for 8.9.x.
Comment #52
vsujeetkumar CreditAttribution: vsujeetkumar at Material for Drupal India Association commentedThis is the interdiff, Forgot to upload.
Comment #53
NWOM CreditAttribution: NWOM commentedLooks like this needs a re-roll for both 9.1.x and 9.2.x. First is a re-roll for 9.1.x. No need for an interdiff, since nothing was changed (I tried making one regardless though, and it failed for some reason).
Comment #54
NWOM CreditAttribution: NWOM commentedAnd here is the re-roll for 9.2.x
Comment #56
vsujeetkumar CreditAttribution: vsujeetkumar at Material for Drupal India Association commentedFixing tests for 9.2.x.
Comment #58
SerShevchykThe patch #56 works fine on 9.2.8
Comment #59
danflanagan8Here's a re-rolled patch that should apply on 9.2.x, 9.3.x, and 9.4.x. I'm changing the target branch for this fix to 9.4.x.
This is really close to being done, but the feedback from #42 has not been fully addressed yet. I will follow with a patch that addresses that feedback after confirming that the re-roll passes.
Comment #60
danflanagan8Seeing as the re-roll applied and passed, I am adding a new patch that fully addresses the comments in #42. We have to move the optional parameter to the end of the list of arguments. Note that there is typically NOT any test coverage added fo these kinds of deprecations, so we don't need to add any test coverage.
My understanding is that we've missed the time for deprecating for removal in 10.0.0. I've updated the deprecation notice to reflect the timeline as I understand it.
I'll also unassign this because I suspect @tim.plunkett isn't actively working on it. :)
Comment #61
Farnoosh CreditAttribution: Farnoosh commentedPatch #56 worked on 9.2.9. Thank you!
Comment #62
xaa CreditAttribution: xaa as a volunteer commentedPatch #60 working on 9.3.6 as well. Thank you!!
Comment #63
jessehsJust in case anyone is looking for it... Here is a combination of the patch in #60, plus additions to make it work with 9.3.7 that is also patched with the synchronized layout override translations patch here.
Comment #64
Ron Collins CreditAttribution: Ron Collins commentedPatch #60 fixed my issue. Drupal 9.3.9.
I haven't used Layout Builder much.
My issue was that I created and inserted a block on my local, exported config and pushed it to a remote but then couldn't edit the layout on the remote. Removing the block from my local, exporting the config again and pushing to the remote still resulted in a broken layout on the remote.
This patch allows me to edit the config on the remote.
Comment #65
Luke.Leber#60 seems to be a very elegant solution here. It has most of the features that I'd hope for:
This solution even handles uncommon scenarios / irresponsible use cases like people deleting database rows directly.
One improvement that I'd love to see is for there to be some sort of classing applied to the broken block message. This would give themes the ability to:
Thoughts?
Comment #66
prasanth_kp CreditAttribution: prasanth_kp as a volunteer and at Zyxware Technologies commentedApplied patch #60 fixed my issue Drupal 9.3
Comment #67
npcoder CreditAttribution: npcoder as a volunteer commentedI have the following configuration:
Webserver: Apache/2.4.38 (Debian)
I had the same issue
and applied patch #60.
After that, I got another issue. I clicked on the 'Edit' button of the node and clicked on the 'Layout' tab. As soon as I clicked on the 'Layout' tab, I see the white blank page spinning for a long time.
I stop the loading page and checked the Drupal log message. The following two messages were generated:
My Finding:
I had enabled the Revison option for the specific Content Type where layoutbuilder was implemented.
Once removed the Revison, it worked.
Though it was a temporary fix, we still need revision on the content type.
Appreciate your help.
Comment #69
alphawebgroupre-roll of #63 for 9.5.x which is also patched with the synchronized layout override translations patch here.
Comment #70
flyke CreditAttribution: flyke commentedPatch #60 works on Drupal 9.4.1. Thanks !
Comment #71
mattjones86This patch doesn't seem to apply with the MR from #2942975: [PP-1] Expose Layout Builder data to REST and JSON:API.
Not managed to work out which lines are conflicting yet.
Comment #72
pfrenssen#60 is still the current patch. I have reviewed it. The fix looks sound, and has sufficient test coverage.
It still applies cleanly to 9.4.x up to 10.1.x. In the meantime 10.0.x and 10.1.x are in development so I started test rounds. What is missing is executing the tests on their own. We should see the original error message appearing in the tests. I am uploading the test-only version of patch #60. I have made no changes.
Comment #74
pfrenssenTest proves that an exception was being thrown (even though the test output doesn't include the exact exception), so the test is correctly detecting the failure.
The patch in #60 looks RTBC. Thanks everyone!
Comment #75
alexpottThe deprecation message needs to be updated for 9.5.x since we won't change a constructor in 9.4.x and the issue summary needs to be updated to describe why logging is the correct solution.
Comment #76
rkelbel48 CreditAttribution: rkelbel48 at Sparkbox commentedThe patch in #60 works for me on Drupal 9.4.7. Thank you!
Comment #78
GafgarionMoruaThe patch in #60 works for me on Drupal 9.5.5
Comment #79
neclimdulUpdated patch to move this forward. moved deprecation to 10 as the latest release this would go in. Updated deprecation to match standard format. Needs Change Record to link to in the deprecation.
I don't know how to address the logging concern in #75 to update the issue summary. Why wouldn't you log the an error? Without logging something it would be one of those unknoweable unfixable errors right?
Comment #81
alecsmrekar CreditAttribution: alecsmrekar as a volunteer commentedHere's a small adjustment to #60 to allows admins to see the broken blocks, instead of suppressing the error "This block is broken or missing..."
Comment #82
alecsmrekar CreditAttribution: alecsmrekar as a volunteer commentedAttaching patch and interdiff
Comment #83
Farnoosh CreditAttribution: Farnoosh as a volunteer commentedHaving this error on Layout builder of an entity in my case the taxonomy term page in Core 10.0.10, so this patch is against 10.0.10
Comment #84
andyg5000I like the approach in #82. Show the error that blocks are missing to those that have access.
Comment #85
Rajab Natshah CreditAttribution: Rajab Natshah at Vardot for Vardot commentedRe-role for the patch from #82 to apply for Drupal
10.2.1
Comment #86
pradhumanjain2311 CreditAttribution: pradhumanjain2311 at OpenSense Labs for DrupalFit commentedThe issue is in
@trigger_error('The logger service must be passed to InlineBlock::__construct(). It was added in drupal:9.4.0 and will be required before drupal:11.0.0.', E_USER_DEPRECATED);
as it is not in correct format.
%thing% is deprecated in %deprecation-version% and is removed from %removal-version%. %extra-info%. See %cr-link%
https://www.drupal.org/about/core/policies/core-change-policies/drupal-deprecation-policy
Comment #87
anpolimusAttempt tp fix PHPSTAN.
Comment #88
anpolimusComment #89
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue.
While you are making the above changes, we recommend that you convert this patch to a merge request. Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)
Comment #93
carolpettirossi CreditAttribution: carolpettirossi at ImageX commentedI created an MR with code from patch #87 as recommended by the "needs-review-queue-bot"
Comment #94
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #95
carolpettirossi CreditAttribution: carolpettirossi at ImageX commentedStill getting the PHPCS error on
trigger_error
. However, I'm wondering if thattrigger_error
is needed. Is there an intention to make$logger
required in a future Drupal version? If yes, do we need a Change Record to link to?Comment #96
DanielVezaCorrect yeah we would need a CR to be made for this as the logger is now required by
InlineBlock
In my opininon, the
trigger_error
message should be formatted like existing examples. This example also includes a CR that could be used as a starting point.Comment #98
froboyI've updated the message and created... 🥁 my first ever change record (please be gentle).
Thanks to @DanielVeza for the helpful example. I tried to follow that model, although I couldn't find any good examples of the constructor being called. I instead opted to use [#3436810] as an example of a constructor change. I'm very much open to suggestions for better examples there.
Comment #99
froboyTest failures seem to be unrelated:
Comment #100
smustgrave CreditAttribution: smustgrave at Mobomo commentedHiding patches for clarity.
Left some comments on the MR.
Leaving issue summary tag if that could be cleaned up please. Proposed solution seems like a question and there are some TBD spots. If there aren't, for example, UI changes it's fine to just N/A there.
Comment #101
froboyThanks for the feedback @smustgrave. I've resolved the MR comments and taken a pass at updating the issue summary.
Comment #102
smustgrave CreditAttribution: smustgrave at Mobomo commentedThanks MR appears to have phpcs errors
Comment #103
froboyI've satisfied phpcs, but it looks like
Drupal\Tests\Composer\Plugin\Scaffold\Functional\ManageGitIgnoreTest
is still failing.Comment #104
smustgrave CreditAttribution: smustgrave at Mobomo commentedWould recommend rebasing the branch.
Comment #105
froboySorry... took a couple tries but I successfully rebased and tests are now passing.
Comment #106
smustgrave CreditAttribution: smustgrave at Mobomo commentedBelieve feedback has been addressed
Comment #107
quietone CreditAttribution: quietone at PreviousNext commentedThis needs a title update so it makes sense in the git log.
Comment #108
smustgrave CreditAttribution: smustgrave at Mobomo commentedDone.
Comment #109
alexpottI've asked a couple of questions on the MR.