Skip to content

AbstractBlock::getParentBlock() returns false due to missing “head.additional” block

We are encountering an issue on our store where sometimes the MagentoFrameworkViewElementAbstractBlock::getParentBlock() method returns false. We traced this back to the fact that the head.additional block is missing in the layout.

However, this issue only occurs in our production environment and is not reproducible in staging or locally, even when using the same database and cache. The issue is temporarily resolved by flushing the layout cache, after which the page renders correctly.

This issue seems to occur primarily on one custom page. This page is pretty basic and does not have any additional logic:

<?php

namespace VendorModuleControllerIndex;

use MagentoFrameworkAppActionHttpGetActionInterface;
use MagentoFrameworkAppResponseInterface;
use MagentoFrameworkControllerResultInterface;
use MagentoFrameworkViewResultPageFactory;
use MagentoStoreModelStoreManagerInterface;
use MagentoThemeBlockHtmlBreadcrumbs;

class Index implements HttpGetActionInterface
{
    public function __construct(
        private readonly PageFactory $resultPageFactory,
        private readonly StoreManagerInterface $storeManager
    ) {
    }

    /**
     * @return ResultInterface|ResponseInterface
     */
    public function execute()
    {
        $resultPage = $this->resultPageFactory->create();
        $breadcrumbs = $resultPage->getLayout()->getBlock('breadcrumbs');
        if ($breadcrumbs instanceof Breadcrumbs) {
            $breadcrumbs->addCrumb(
                'home',
                [
                    'label' => __('Home'),
                    'title' => __('Go to Home Page'),
                    'link' => $this->storeManager->getStore()->getBaseUrl(),
                ]
            )->addCrumb(
                'search',
                ['label' => __('Search'), 'title' => __('Search')]
            );
        }

        return $resultPage;
    }
}

Here are the details of the investigation so far:

  1. We verified that the head.additional block is not removed in any of the layout XML files.
  2. We performed a full-text search for head.additional across the entire project to check if any code is removing it, but no results were found.
  3. While debugging during the issue, it seems that the head.additional block is already missing from the result of MagentoFrameworkViewPageLayoutReader::getPageLayoutMerge.
  4. While debugging into MagentoFrameworkViewElementAbstractBlock::getParentBlock trying to get the missing block we did a diff of $this->getLayout()->getXmlString(); when the parent block is missing and when it is present. Here the result:
--- /home/user/.config/JetBrains/PhpStorm2024.3/scratches/layout_getXmlSring_innerhalb_getParentBlock_bugged.xml        2025-02-26 12:34:24.328654965 +0100
+++ /home/user/.config/JetBrains/PhpStorm2024.3/scratches/layout_xmlstring-works.xml      2025-02-26 12:49:54.082643119 +0100
@@ -20,12 +20,12 @@
     </body>
     <head>
         <meta name="viewport" content="width=device-width, initial-scale=1"/>
-        <css src="css/styles.css"/>
+        <css src="css/styles.css" content_type="css"/>
     </head>
     <head>
-        <font src="fonts/open-sans-v18-latin-600.woff2"/>
-        <font src="fonts/open-sans-v18-latin-700.woff2"/>
-        <font src="fonts/open-sans-v18-latin-regular.woff2"/>
+        <font src="fonts/open-sans-v18-latin-600.woff2" content_type="font"/>
+        <font src="fonts/open-sans-v18-latin-700.woff2" content_type="font"/>
+        <font src="fonts/open-sans-v18-latin-regular.woff2" content_type="font"/>
         <remove src="Smile_ElasticsuiteTracker::js/tracking.js"/>
     </head>
     <update handle="default_head_blocks"/>
@@ -350,7 +350,7 @@
     <body>
         <referenceContainer name="before.body.end">
             <block class="MagePalEnhancedEcommerceBlockJsComponent"
-                   template="MagePal_EnhancedEcommerce::js-component.phtml">
+                   template="MagePal_EnhancedEcommerce::js-component.phtml" name="before.body.end_schedule_block0">
                 <arguments>
                     <argument name="component_name" xsi:type="string">addToCartAjaxDataLayer</argument>
                 </arguments>
@@ -470,13 +470,14 @@
             <block class="MagePalDataLayerBlockPagesAllPage" name="magepal_datalayer_allpage"/>
         </referenceBlock>
         <referenceContainer name="after.body.start">
-            <block class="MagePalDataLayerBlockDataLayer" template="MagePal_DataLayer::data_layer.phtml"/>
+            <block class="MagePalDataLayerBlockDataLayer" template="MagePal_DataLayer::data_layer.phtml"
+                   name="after.body.start_schedule_block1"/>
         </referenceContainer>
     </body>
     <body>
         <referenceContainer name="before.body.end">
             <block class="MagePalGoogleAnalytics4BlockJsComponent"
-                   template="MagePal_GoogleAnalytics4::js-component.phtml">
+                   template="MagePal_GoogleAnalytics4::js-component.phtml" name="before.body.end_schedule_block2">
                 <arguments>
                     <argument name="component_name" xsi:type="string">addToCartAjaxGa4DataLayer</argument>
                 </arguments>
@@ -578,7 +579,7 @@
         <referenceBlock name="factfinder.campaign.pushed.products" remove="true"/>
     </body>
     <head>
-        <script src="Smile_ElasticsuiteTracker::js/tracking.js"/>
+        <script src="Smile_ElasticsuiteTracker::js/tracking.js" content_type="js"/>
     </head>
     <body>
         <referenceBlock name="head.additional">
@@ -1446,7 +1447,7 @@
         </referenceBlock>
     </body>
     <head>
-        <script src="Vendor_FactFinder::js/client/dist/client-bundle.js" defer="defer"/>
+        <script src="Vendor_FactFinder::js/client/dist/client-bundle.js" defer="defer" content_type="js"/>
     </head>
     <body>
         <referenceBlock name="header-content">
@@ -1520,4 +1521,4 @@
             <block name="quickorder.loader" template="Vendor_Quickorder::loader.phtml"/>
         </block>
     </body>
-</layout>
 No newline at end of file
+</layout>

Weird part about this diff is that the only changes are some attributes and no structural changes.

We are using the Hyvä theme with Hyvä Checkout if that matters.

Has anyone encountered something similar or can provide guidance on how to further debug the issue? Any insights on why head.additional might be missing would be highly appreciated.