ApiLayoutController::getRegionForComponentInstance doesn't work well with nested components if there are multiple regions.

Created on 9 July 2025, 3 months ago

Overview

We recently faced an issue where we couldn't use nested components in an XB page that has multiple regions.

Steps to reproduce

  1. Have multiple regions set up.
  2. Place two components one with a prop and another one with a slot in a component with slots.
  3. Place another component with a prop inside the nested component.
  4. Fill the value of prop in first component. This one works.
  5. Fill the value of prop in 2nd component.(The one in nested component).
  6. See that the network call for this last one fails with 5xx error.

Expected result

Nested components should work well.

This fails at ApiLayoutController::267 because `$regionForComponentId` is null and it's not able to get the region even though content region exists under which this component is placed.

Proposed resolution

User interface changes

๐Ÿ› Bug report
Status

Active

Version

0.0

Component

โ€ฆย to be triaged

Created by

๐Ÿ‡ฎ๐Ÿ‡ณIndia amangrover90

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

Merge Requests

Comments & Activities

  • Issue created by @amangrover90
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    This fails at ApiLayoutController::267 because $regionForComponentId is null and it's not able to get the region even though content region exists under which this component is placed.

    That's

          if ($regionForComponentId !== XbPageVariant::MAIN_CONTENT_REGION) {
            if (!$page_regions[$regionForComponentId]->access('edit')) {
              throw new AccessDeniedHttpException(sprintf('Access denied for region %s', $regionForComponentId));
            }
    

    So โ€ฆ this would mean that $page_regions[$regionForComponentId] resolves to NULL, meaning that $regionForComponentId is NOT one of the existing PageRegion config entities?! ๐Ÿ˜ฑ

    Can you please apply this patch to get a more precise error message?

    $ git diff
    diff --git a/src/Controller/ApiLayoutController.php b/src/Controller/ApiLayoutController.php
    index f34ce46cc..570082478 100644
    --- a/src/Controller/ApiLayoutController.php
    +++ b/src/Controller/ApiLayoutController.php
    @@ -264,6 +264,9 @@ final class ApiLayoutController {
         if (!empty($page_regions)) {
           $regionForComponentId = $this->getRegionForComponentInstance($data['layout'], $componentInstanceUuid);
           if ($regionForComponentId !== XbPageVariant::MAIN_CONTENT_REGION) {
    +        if (!array_key_exists($regionForComponentId, $page_regions)) {
    +          throw new \LogicException(sprintf("Component instance %s is in a region (%s) for which no PageRegion config entity exists. Existing PageRegions: %s.", $componentInstanceUuid, $regionForComponentId, implode(', ', array_keys($page_regions))));
    +        }
             if (!$page_regions[$regionForComponentId]->access('edit')) {
               throw new AccessDeniedHttpException(sprintf('Access denied for region %s', $regionForComponentId));
             }
    
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Oh wait:

    because $regionForComponentId is null

    If true, this would most likely be a bug in \Drupal\experience_builder\Controller\ApiLayoutController::getRegionForComponentInstance()?

    What would be really helpful is you sharing the full request body that triggered that 500 response ๐Ÿ™ That would allow us to easily write a failing test case to ApiLayoutControllerPatchTest.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mglaman WI, USA

    I walked through the xdebug of this. The component was in the `content` region. I think the bug is in the `slots` code

              // Maybe it's not a component, but a slot inside a component.
              foreach ($componentData['slots'] as $slotData) {
                foreach ($slotData['components'] as $slotComponentData) {
                  if ($slotComponentData['uuid'] === $componentInstanceUuid) {
                    return TRUE;
                  }
                }
              }
    

    It was nested 2 or 3 levels deep.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Bumping priority and tagging , because AFAICT ๐Ÿ› Created XB Pattern didnโ€™t include all components Active is a duplicate bug report!

    Tom, could you take a look at this today? ๐Ÿ™

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia amangrover90

    Uploaded the payload for which there was 500 error. It fails trying to calculate the regionForComponentId.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    This blocks #3535078, see #3535078-9: [PP-1] Created XB Pattern didnโ€™t include all components โ†’ . More likely: that is a duplicate of this issue: different symptom, same root cause. Still, let's double-check there after this lands ๐Ÿ‘

  • First commit to issue fork.
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • Pipeline finished with Failed
    3 months ago
    Total: 681s
    #543967
  • Pipeline finished with Success
    3 months ago
    Total: 742s
    #543995
  • ๐Ÿ‡ช๐Ÿ‡ธSpain isholgueras

    This is ready with all tests green. Let me know if we can create a follow-up ticket for tests or if we should include here the tests

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Yes, we do, hence the tag ๐Ÿ˜‡

    See #9 for a sample payload, but it sounds like you were able to reproduce this yourself already :)

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • First commit to issue fork.
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    I think this should be a beta blocker, its pretty easy to get this error.

    Pushed a failing test and rebased off 0.x

    If you checkout 185d8c32 and run ApiLayoutControllerPatchTest it fails.

    We already had most of the required structure in XbTestSetup, just needed to do some fernangling to mirror the nesting.

    Adding the tag, asking for forgiveness not permission etc

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    2 questions on the MR โ€” one about a remaining @todo, one about something I don't understand.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Thanks!

    Landing ๐Ÿ› Add rudimentary conflict prevention to the Config Auto-save end-point Active first though.

  • Pipeline finished with Failed
    3 months ago
    Total: 783s
    #544967
  • ๐Ÿ‡ช๐Ÿ‡ธSpain isholgueras

    โ€ฆ but let's land !1204 first, that is much harder to reroll.

    Sure! feel free to throw it back to me if we need a reroll here.

  • ๐Ÿ‡ช๐Ÿ‡ธSpain penyaskito Seville ๐Ÿ’ƒ, Spain ๐Ÿ‡ช๐Ÿ‡ธ, UTC+2 ๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    ๐Ÿ› Add rudimentary conflict prevention to the Config Auto-save end-point Active is in! Merging this as soon as CI passes.

    @penyaskito THAT WAS FAST ๐Ÿ˜ฑ

  • Pipeline finished with Skipped
    3 months ago
    #545061
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024