We have a content type called "Blog".
You can see that it has the correct field for "layout_builder__layout".

This content type has the "Default" display mode set to use Layout at `/admin/structure/types/manage/blog/display`

We create a new display mode called "Blog Card" at `/admin/structure/display-modes/view/add/node`
In "Manage Display" of the content type "Blog" we add the Display mode we just created.

This starts as using Layout to manage display.

On the new display mode, "Blog Card" disable Layout at `/admin/structure/types/manage/blog/display/blog_card`
Go back to "manage fields" and you see that the "layout_builder__layout" field is missing.

Creating a new Blog node results in a nasty error message :
The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">InvalidArgumentException</em>: Field layout_builder__layout is unknown. in <em class="placeholder">Drupal\Core\Entity\ContentEntityBase->getTranslatedField()</em> (line <em class="placeholder">586</em> of <em class="placeholder">core/lib/Drupal/Core/Entity/ContentEntityBase.php</em>). <pre class="backtrace">Drupal\Core\Entity\ContentEntityBase->get('layout_builder__layout') (Line: 242)
Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay->getRuntimeSections(Object) (Line: 207)
Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay->buildMultiple(Array) (Line: 321)
Drupal\Core\Entity\EntityViewBuilder->buildComponents(Array, Array, Array, 'full') (Line: 22)
Drupal\node\NodeViewBuilder->buildComponents(Array, Array, Array, 'full') (Line: 263)
Drupal\Core\Entity\EntityViewBuilder->buildMultiple(Array) (Line: 220)
Drupal\Core\Entity\EntityViewBuilder->build(Array)
call_user_func(Array, Array) (Line: 378)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 226)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 227)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 117)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
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: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 665)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
</pre>
The important part I think :
The website encountered an unexpected error. Please try again later.InvalidArgumentException: Field layout_builder__layout is unknown.
Indicating the field is missing.
| Comment | File | Size | Author |
|---|---|---|---|
| #17 | confusing_confirm_form_texts.png | 73.42 KB | xjm |
| #14 | 2990517-field-14.patch | 5.17 KB | tim.plunkett |
| #14 | 2990517-field-14-interdiff.txt | 1.32 KB | tim.plunkett |
| #10 | 2990517-field-10.patch | 5.03 KB | tim.plunkett |
| #3 | 2990517-field-3-PASS.patch | 6.7 KB | tim.plunkett |
Comments
Comment #2
tim.plunkettI'm facepalming VERY hard over here. Thanks for filing this!
Comment #3
tim.plunkettThis is partially due to how creating new view modes works: it copies 100% of the values over from default.
Even values that currently don't make sense, like enabling overrides for other view modes.
Until #2907413: Consider supporting Layout Builder Overrides for other view modes happens, that shouldn't be possible...
But let's futureproof this anyway.
The field should not be removed until no other view modes of that bundle have overrides enabled.
Not sure if there's a better way to do that than this entity query, but it should work.
Comment #5
tim.plunkettLove getting it red/green on the first try.
Comment #6
neclimdulWanted to just RTBC since its nice and clean but....
Hard computer problem, naming things. Since this conditionally removes instead of always removes, should it maybe be "cleanSectionField()" or "pruneSectionField()"?
Comment #7
tim.plunkettTagging to work on this next week.
Comment #8
sugaroverflow commentedreviewing at MWDS
Comment #9
xjmThis sounds critical. Is there a mitigation I'm missing? I don't quite follow #3.
Comment #10
tim.plunkett#3 wasn't mitigation or anything, just explaining how we ended up here.
Rerolled after #2998215: PHP notices/warnings when managing display for non-default view mode when LB is enabled w/ overrides
Comment #11
tim.plunkettComment #12
phenaproximaLooks pretty good to me...
Minor point, but does this really need to take any parameters? The $entity_type_id, $bundle, and $field_name are all known to the display entity already.
Eh, I guess this is a nitpick, really, seeing as how addSectionField() follows the same pattern. Just pointing it out.
Can we use $this->getEntityTypeId() instead of $this->entityTypeId?
Comment #13
phenaproximaI echo @neclimdul's sentiment about either renaming this method, or changing the doc comment to explain that the field *may* not be removed.
Comment #14
tim.plunkett#12.1
Yeah, this is done for parallelism with addSectionField()
#12.2
Fixed
#13.2
Adjusted/expanded the docblock
Comment #15
phenaproximaThanks, @tim.plunkett. This looks excellent. RTBC on green.
Comment #16
xjmWow, I think this is the most critical non-security bug I've seen since... maybe since release. Didn't even realize the full impact when I skimmed it before. Change a display mode and break all your site's content!
I encountered #2289551: Clarify what 'locked' means for a config entity and whether it's okay for code to rely on a locked config entity existing and (I think) #2941189: Confirmation form for disabling per-entity layout overrides shows a success message and should not in the process of testing this; just adding them to the related issues for posterity.
I also noticed that the confirm title and description are confusing:

The title should actually be something like "Are you sure you want to disable Layout Builder for the Teaser display?" or perhaps simply "Are you sure you want to disable this layout?" The description should be something like "This will remove all your layout data for the Teaser display of Article content". That exists in HEAD, though
Normally I'd want the missing followup filed prior to committing the patch, but that bug is there in HEAD too and this issue is bad enough that I don't want to block it on anything. Will probably commit this once I finish reviewing the test.
Comment #17
xjmComment #18
xjmfoobarisn't the best test content; I actually had to look up the second argument ofdrupalCreateUser()to figure it out.Spoiler: It's just the username. I don't think we actually need it here as it's an optional argument (random in the 99% case where it's not specified) and we don't use it in this test? Not really a big deal.
The comma here isn't grammatically feasible.
Even with the
pageTextNotContains(), is this specific enough? E.g. we might change the flow and this could match the sidebar link or something. OTOH this isn't what we're actually testing in this test, so it's probably good enough.At first this looked redundant; one would think
clickLink()would account for the assertion preceding it. But then I remembered that (IIRC) clicking a link that doesn't exist gives some incomprehensible failure message, so this likely makes sense.These are NBD and are potentially copied from other LB tests, so I don't think they need to be blocking (for the same reasons as in #16).
Comment #21
xjmCommitted and pushed to 8.7.x and 8.6.x. Thanks!
Followups for #16 and #18 would be nice.
Comment #22
xjmComment #24
stancsmith@gmail.com commentedWhen attempting to patch 8.7.3, I got the following error from composer. Any suggestions?
The same patch process created LayoutBuilderEntityViewDisplay.php.rej with this:
Here is the relevant section from composer.json: