Breadcrumbs block within Layout Builder causes errors when moving blocks

Created on 22 July 2020, over 4 years ago
Updated 13 August 2024, 3 months ago

Problem/Motivation

Layout Builder throws errors when the system Breadcrumbs block is in a layout and any blocks are moved. Further, after moving the Breadcrumbs block, the "Move" contextual link stops working.

The error looks something like this:

InvalidArgumentException: Invalid UUID "first" in Drupal\layout_builder\Section->getComponent() (line 177 of /var/www/web/core/modules/layout_builder/src/Section.php).

Steps to reproduce

Simple

  1. Do a Standard Install
  2. Enable Layout Builder
  3. Configure Basic Page content type to use Layout Builder
  4. Add a Breadcrumbs block to the Basic Page layout
  5. Move any block via drag-and-drop in the Basic Page layout through the Layout Builder UI
  6. Go to the Recent Log Messages and see something about an invalid UUID

More Interesting

  1. Do a Standard Install
  2. Enable Layout Builder
  3. Configure Basic Page content type to use Layout Builder
  4. Add a Breadcrumbs block to the Basic Page layout
  5. Move any block to a different section via drag-and-drop in the Basic Page layout through the Layout Builder UI
  6. Click the "Move" contextual link for the any block. Instead of the offscreen dialog flying in, the throbber will just give up.
  7. Right-click the "Move" contextual link for any block and open the link in a new tab. WSOD.

Proposed resolution

The error results for the Breadcrumbs getting built and rebuilt as part of the layout builder preview. It tries to build breadcrumbs for the layout_builder.move_block_form route and the title callback is called with bad arguments.

Current Proposal

We can add a LayoutBuilderBreadcrumbBuilder class and a layout_builder.breadcrumb to build breadcrumbs on routes related to moving blocks. See #20.

Older proposals

Old Proposal 1
Add some defensive coding into \Drupal\layout_builder\Form\MoveBlockForm::title to confirm that the uuid argument looks like a uuid before using it in a getComponent() call. Return some sort of placeholder text as the title instead.

Old Proposal 2
SystemBreadcrumbBlock::build could vary depending on context. This would depend on #3027653: Allow block and layout plugins to determine if they are being previewed getting fixed first.

Old Proposal 3
SystemBreadcrumbBlock::build do a special case when the route name is layout_builder.move_block

Other proposals?

Remaining tasks

Write tests (this is started in #14 but can probably be improved)
Add a fix

User interface changes

TBD

API changes

TBD

Data model changes

TBD

Release notes snippet

TBD

Original Report

When using the drag and drop interface for Layout Builder, dragging a custom block generates the following error:

InvalidArgumentException: Invalid UUID "first" in Drupal\layout_builder\Section->getComponent() (line 177 of /var/www/web/core/modules/layout_builder/src/Section.php).

Where "first" is the label of the region inside the section. This is thrown on any move, whether between sections or not. There is no further backtrace listed, but I was able to track it back to MoveBlockForm::title. This error does not get thrown if I open the Move Block Form from the contextual menu.

The only module we have installed I know of that does anything with this form is layout_builder_restrictions, but I am not seeing anything in that code that would do this.

Just being an old code rat, I am not conversant enough with the JS Drag and Drop interface to be able to troubleshoot this further without some help, and I haven't seen this in any other issue queues.

🐛 Bug report
Status

RTBC

Version

11.0 🔥

Component
Layout builder 

Last updated about 11 hours ago

Created by

🇺🇸United States R_H-L

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇺🇸United States smustgrave

    This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

    Can confirm the issue in D10 following the steps from the issue summary.
    Applying patch and clearing cache fixes the issue

    Moving to NW for a change record though to announce the new service for layout builder.

  • 🇸🇮Slovenia alecsmrekar

    We could also add a uuid regex to the routing file, which would prevent accessing the route with unexpected arguments.

    The attached patch prevent the error from being thrown.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    Patch Failed to Apply
  • 🇸🇮Slovenia alecsmrekar

    Fix for patch not applying

  • 🇧🇪Belgium RandalV

    Thank you for your patch, alecsmrekar, it seems to work.

    It seems to work, but I am however unclear on why this issue pops up at all. why is the `layout_builder.move_block_form`-route being triggered when the arguments clearly call for the `layout_builder.move_block` route.

    I'm wondering if changing the path for one of the two routes would be a more stable solution?
    Two routes with very similar paths and arguments, that seems like asking for trouble to me.

    Perhaps all non-publicly accessible routes (like ajax routes) should get some prefix, for example.

  • First commit to issue fork.
  • Pipeline finished with Failed
    4 months ago
    Total: 209s
    #222230
  • Status changed to Needs review 4 months ago
  • 🇳🇿New Zealand danielveza Brisbane, AU

    Adding an entirely new BreadcrumbBuilder for this block feels excessive. I propose we simply check if the block is in preview and display the fallback text if it is. This was suggested in #19 and that issue has now landed so this is possible.

    Added a MR with this approach with test coverage.

  • Status changed to Needs work 4 months ago
  • The 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.)

  • Pipeline finished with Failed
    4 months ago
    #222234
  • Pipeline finished with Success
    4 months ago
    Total: 611s
    #222240
  • Status changed to Needs review 4 months ago
  • 🇳🇿New Zealand danielveza Brisbane, AU

    Tests on MR is green now.

  • Status changed to Needs work 4 months ago
  • 🇺🇸United States danflanagan8 St. Louis, US

    I like the solution in the MR that relies on the preview flag. I'm going to remove the "Needs change record" tag because this approach does not need a CR.

    I ran the test only job and it failed, which is good.

    I'm hardly impartial because I wrote the first fail test for this in #20, but I like my test better. To me the new test doesn't clearly demonstrate that the breadcrumb block is currently malfunctional; instead it looks like we're just focused on changing the preview text. I think asserting the class .block-system-breadcrumb-block is more robust and illustrative than asserting the preview text (though asserting the preview text in addition to the class would be good.)

    I also personally prefer the approach of adding a few assertions to an existing test, which is almost certainly more performant than a dedicated functional test. There's something to be said for the separation of concerns, though, so I won't put up a fight there.

  • 🇳🇿New Zealand danielveza Brisbane, AU

    I think asserting the class .block-system-breadcrumb-block is more robus

    Don't personally feel strongly about this, can add it in along with the preview test check.

    I also personally prefer the approach of adding a few assertions to an existing test

    I disagree with this one for a couple of reasons

    This issue is in the breadcrumbs block, not Layout Builder, so the test should live in the system module, not Layout Builder
    Layout Builder tests are already doing too much in single files and need to be split, so I don't want to add more bloat.

    Moving the block is vital to triggering the error, so I think the test needs to move the block.

    I'm 50/50 on this one. FunctionalJS tests are slow and I don't think it's needed in this case. I fully understand writing a test that runs the exact steps to trigger the issue, but in this case I think we can be confident that the changes to the build function of the breadcrumbs block also resolve the dragging issue, and they're being tested in this issue.

    That being said, I don't feel strongly about this one and I can see the other side of the argument for sure. If someone would want to rewrite it as a FunctionalJS test I wouldn't block it

  • 🇺🇸United States danflanagan8 St. Louis, US

    This being a bug, we're really supposed to add a test that triggers the error unless the issue satisfies a special set of criteria: https://www.drupal.org/about/core/policies/core-change-policies/core-gat...

    Looking at the functional test on the MR again, if all we're asserting is that the build function returns a certain string, then we could probably get away with a Unit test and make it really fast.

  • Pipeline finished with Success
    4 months ago
    Total: 562s
    #231598
  • Status changed to Needs review 4 months ago
  • 🇳🇿New Zealand danielveza Brisbane, AU

    Rewrote the test to be FunctionalJS that follows the unhappy path

  • Status changed to RTBC 4 months ago
  • 🇺🇸United States smustgrave
    1) Drupal\Tests\system\FunctionalJavascript\Block\BreadcrumbLayoutBuilderPreviewTest::testBreadcrumbsInLayoutBuilder
    RuntimeException: Unable to complete AJAX request.
    /builds/issue/drupal-3160785/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php:117
    /builds/issue/drupal-3160785/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php:38
    /builds/issue/drupal-3160785/core/modules/system/tests/src/FunctionalJavascript/Block/BreadcrumbLayoutBuilderPreviewTest.php:83
    ERRORS!
    Tests: 1, Assertions: 7, Errors: 1.

    Coverage appears to be there

    I followed the simple approach for testing in the summary and can confirm the MR does fix the issue.

    Believe this one is good.

  • 🇳🇿New Zealand quietone

    I read through the issue summary and comments. There are no unanswered questions. I didn't review the MR or test the change.

  • 🇪🇸Spain unstatu

    I confirm that #29 fixes the issue.

  • 🇬🇧United Kingdom longwave UK

    To me the FunctionalJavaScript test is good but in the wrong place - it is primarily testing the functionality of Layout Builder even if the block belongs to system.module. If we ever move LB out of core then the test would have to go with it. Perhaps we should also add a small kernel test in system.module to prove that the block behaviour is correct outside of LB?

Production build 0.71.5 2024