Magento2: Magento 2.2.0 issues with layouts

Created on 28 Sep 2017  路  32Comments  路  Source: magento/magento2


Preconditions


  1. Magento 2.1.9
  2. PHP 7.0.18
  3. MySQL 5.7.18

Steps to reproduce

  1. Upgrade from 2.1.9 to 2.2.0
  2. Browser front page

Expected result

  1. No errors!

Actual result


Seems that some layouts are incorrect:

Exception #0 (Magento\Framework\Config\Dom\ValidationException): Element 'referenceBlock', attribute 'ifconfig': The attribute 'ifconfig' is not allowed.
Line: 12

Element 'referenceBlock', attribute 'as': The attribute 'as' is not allowed.
Line: 12


Exception #0 (Magento\Framework\Config\Dom\ValidationException): Element 'referenceBlock', attribute 'ifconfig': The attribute 'ifconfig' is not allowed.
Line: 12

Element 'referenceBlock', attribute 'as': The attribute 'as' is not allowed.
Line: 12

I know that it's hard to find what's the problem. But my Magento works fine on Magento 2.1.9 what changes about defining layouts can break now with Magento 2.2.0?

Clear Description Confirmed Format is valid non-issue

Most helpful comment

@slayerbleast are you using Windows?

All 32 comments

This is not a bug, those attributes are not allowed when using referenceBlock and you should locate them in your code a remove them.

Hi @slayerbleast
Unfortunately, I could not reproduce the issue as you described it.
Please add more details to your description of the steps you followed when identifying this issue.
Layout file, where used attribute 'ifconfig' in element 'referenceBlock' would be helpful.

@slayerbleast are you using Windows?

@jhruehl nothing funny, there were a couple of issues with similar symptoms on Windows which I planned to close :)

My two cents for what it worth:
I had this issue after upgrading 2.1.8 >> 2.2.0 and after debugging it I saw the available attributes for "referenceBlock" tag in: /vendor/magento/framework/View/Layout/etc/elements.xsd

the attributes allowed are: (~ line 313)



This is why an exception is thrown in /vendor/magento/framework/Config/Dom.php (_initDom method).
For some reason that didn't happened before version 2.2.0.. but still, not sure this is a bug...

@arielmorry nice catch! However I checked this schema for 2.0.0, 2.1.0 and 2.2.0 searching for "as", it never changed and allowed for <block, <container, <move and <uiComponent only. Maybe validation didn't work properly before in some cases.

@slayerbleast please remove disallowed "as" attribute from all <referenceBlock and check if the issue disappear.

Yep, for some reason before 2.2.0 we could set these attributes on referenceBlock...
Well the problem is there are so many extension from 3rd party vendors that will break in this new version... they'll need to release new versions.

Why anybody used 'as' in the first place? Did it allow to override alias or was just a copy-paste error?

so many extension from 3rd party vendors that will break in this new version... they'll need to release new versions.

No extension should be allowed for use with 2.2.0 until tested by vendor. There was quite a bit of time to check extensions against 2.2 release candidates and be prepared for stable release.

Received similar error when upgrade to Magento 2.20:

1 exception(s):
Exception #0 (MagentoFrameworkConfigDomValidationException): Element 'referenceBlock', attribute 'ifconfig': The attribute 'ifconfig' is not allowed.
Line: 682

Element 'body': Character content other than whitespace is not allowed because the content type is 'element-only'.
Line: 710

Element 'move': This element is not expected. Expected is one of ( action, arguments, block, container, referenceBlock, uiComponent ).
Line: 777

Element 'referenceBlock', attribute 'ifconfig': The attribute 'ifconfig' is not allowed.
Line: 796

Exception #0 (MagentoFrameworkConfigDomValidationException): Element 'referenceBlock', attribute 'ifconfig': The attribute 'ifconfig' is not allowed.
Line: 682

Element 'body': Character content other than whitespace is not allowed because the content type is 'element-only'.
Line: 710

Element 'move': This element is not expected. Expected is one of ( action, arguments, block, container, referenceBlock, uiComponent ).
Line: 777

Element 'referenceBlock', attribute 'ifconfig': The attribute 'ifconfig' is not allowed.

@slayerbleast, thank you for your report.
This seems to be correct Magento behavior. Please refer to the Community Forums or the Magento Stack Exchange site for advice or general discussion about this.
Otherwise you may submit Pull Request with the suggested changes.

Hi There,
I have found this issue from the theme customized.
First time I using this code and it works in 2.1.9.
<block class="Magento\Framework\View\Element\Text" name="store.links" group="navigation-sections" remove="true"/> <block class="Magento\Framework\View\Element\Template" name="store.settings" group="navigation-sections" template="Magento_Theme::html/container.phtml" remove="true"/>
But when upgrade to CE220 it not working. So i changed it to:
<referenceBlock name="store.links" remove="true" /> <referenceBlock name="store.settings" remove="true" />
And problem have resolved.

Hi @zivendesign thanks. I got this fixed.

It is happen for some wrong syntax at layout files:

For

<referenceContainer name="main.content" class="row">

i have remove _class="row"_ then it is worked

Also

<referenceBlock name="top.links" after="register-link">

need to remove xml attribute after="register-link"

@msawyers

Can you please let me know how you fixed below issue,

Element 'body': Character content other than whitespace is not allowed because the content type is 'element-only'.
Line: 710

I am also experiencing same issue.

Magento 2.2.0 issues with layouts #11116

same issue here

#

Exception #0 (MagentoFrameworkConfigDomValidationException): Element 'referenceBlock', attribute 'ifconfig': The attribute 'ifconfig' is not allowed.

#

The above issue has been arrived on frontend in developer ( not tested in default mode) mode for Magento 2.2.1. I have solved this error by changing mode in production.

Morning,

I hope this helps someone trying to find the particular XML that causes your System to error.

I'll start by saying this isn't recommended practice by any means. But just hopefully provide you a helpful clue to save time. The Exception provided the handles of which XML it included; "E.g" default - but which default.xml!

I spent a while trying to find which XML node exactly was erroring as (In my case it was "<argument>") Which is a very frequently used node in most XMLs throughout module .xml's. It's made more tricky that the error is normally a result of a merged number of XML files.

The very file that actually begins this validation process is at:

Composer

/vendor/magento/framework/View/Model/Layout/Merge.php

Github

/lib/internal/Magento/Framework/View/Model/Layout/Merge.php

Now the Exception that is thrown from Magento references a line on the merged XML file. Thankfully you can view this Merged XML file by adding:

 if ($this->appState->getMode() === \Magento\Framework\App\State::MODE_DEVELOPER) {
        $this->logger->info( $layoutStr ); 
        //Or just echo to browser. 
        //echo "<pre>". $layoutStr ."</pre>"; 
        throw $e;
}

it's then you can see the actual line declared on the Exception (A part of a merged XML) that may, give a stronger clue to where the problem lies. In my case, it was one of the Arguments not properly structured in one of my many Third party modules included.

I personally think the exception report on Developer mode should include the very line of XML that it reports on.

This change has removed a very useful part of referenceBlock that I have used a lot in my modules.

If I need to change the Block class of a Block, ideally I would create a preference in di.xml. But this is not always practical, for example MagentoCatalogBlockProductView is used for loads of different Blocks and I do not necessarily want to change MagentoCatalogBlockProductView for every Block that uses it.

Currently (< 2.2) I achieve this by doing:

<referenceBlock class="Custom\ModuleBlock\Product\View" name="a-block-im-changing"/>

In 2.2.* this is now not possible. It can be made to work again by adding the following line after line 315 in vendor/magento/framework/View/Layout/etc/elements.xsd

<xs:attribute type="xs:string" name="class" use="optional"/>

Does anyone have any suggestions on how to achieve what I've been doing in 2.2 ? If not, I will probably hack the core to continue working the way I have been.

edit

The fact it starts working again after only adding that line into elements.xsd makes me think this feature is meant to exist but has been forgotten about when elements.xsd was changed in 2.2

ttl attibute is also breaks the layout in dev mode

please give me a solution....fast

1 exception(s):
Exception #0 (MagentoFrameworkConfigDomValidationException): Element 'referenceBlock', attribute 'after': The attribute 'after' is not allowed.
Line: 965

Exception #0 (MagentoFrameworkConfigDomValidationException): Element 'referenceBlock', attribute 'after': The attribute 'after' is not allowed.
Line: 965

0 /home/silverg6/public_html/vendor/magento/framework/Config/Dom.php(115): MagentoFrameworkConfigDom->_initDom('

1 /home/silverg6/public_html/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php(111): MagentoFrameworkConfigDom->__construct('xmlns:x...', Object(MagentoFrameworkAppArgumentsValidationState), Array, NULL, '/home/silverg6/...', '%message%nLine:...')

2 /home/silverg6/public_html/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php(66): MagentoFrameworkObjectManagerFactoryAbstractFactory->createObject('Magento\Framewo...', Array)

3 /home/silverg6/public_html/vendor/magento/framework/ObjectManager/ObjectManager.php(56): MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create('Magento\Framewo...', Array)

4 /home/silverg6/public_html/vendor/magento/framework/Config/DomFactory.php(42): MagentoFrameworkObjectManagerObjectManager->create('Magento\Framewo...', Array)

5 /home/silverg6/public_html/vendor/magento/framework/View/Model/Layout/Update/Validator.php(141): MagentoFrameworkConfigDomFactory->createDom(Array)

6 /home/silverg6/public_html/lib/internal/Magento/Framework/View/Model/Layout/Merge.php(413): MagentoFrameworkViewModelLayoutUpdateValidator->isValid('

7 /home/silverg6/public_html/lib/internal/Magento/Framework/View/Model/Layout/Merge.php(396): MagentoFrameworkViewModelLayoutMerge->_validateMergedLayout('LAYOUT_frontend...', 'n

8 /home/silverg6/public_html/generated/code/Magento/Framework/View/Model/Layout/Merge/Interceptor.php(193): MagentoFrameworkViewModelLayoutMerge->load(Array)

9 /home/silverg6/public_html/vendor/magento/framework/View/Layout/Builder.php(86): MagentoFrameworkViewModelLayoutMergeInterceptor->load()

10 /home/silverg6/public_html/vendor/magento/framework/View/Layout/Builder.php(63): MagentoFrameworkViewLayoutBuilder->loadLayoutUpdates()

11 /home/silverg6/public_html/vendor/magento/framework/View/Layout.php(254): MagentoFrameworkViewLayoutBuilder->build()

12 /home/silverg6/public_html/vendor/magento/framework/View/Layout.php(875): MagentoFrameworkViewLayout->build()

13 /home/silverg6/public_html/generated/code/Magento/Framework/View/Layout/Interceptor.php(414): MagentoFrameworkViewLayout->getBlock('page_content_he...')

14 /home/silverg6/public_html/vendor/magento/module-cms/Helper/Page.php(171): MagentoFrameworkViewLayoutInterceptor->getBlock('page_content_he...')

15 /home/silverg6/public_html/vendor/magento/module-cms/Controller/Index/Index.php(43): MagentoCmsHelperPage->prepareResultPage(Object(MagentoCmsControllerIndexIndexInterceptor), 'everything-home...')

16 /home/silverg6/public_html/generated/code/Magento/Cms/Controller/Index/Index/Interceptor.php(24): MagentoCmsControllerIndexIndex->execute(NULL)

17 /home/silverg6/public_html/vendor/magento/framework/App/Action/Action.php(107): MagentoCmsControllerIndexIndexInterceptor->execute()

18 /home/silverg6/public_html/vendor/magento/framework/Interception/Interceptor.php(58): MagentoFrameworkAppActionAction->dispatch(Object(MagentoFrameworkAppRequestHttp))

19 /home/silverg6/public_html/vendor/magento/framework/Interception/Interceptor.php(138): MagentoCmsControllerIndexIndexInterceptor->___callParent('dispatch', Array)

20 /home/silverg6/public_html/vendor/magento/framework/Interception/Interceptor.php(153): MagentoCmsControllerIndexIndexInterceptor->MagentoFrameworkInterception{closure}(Object(MagentoFrameworkAppRequestHttp))

21 /home/silverg6/public_html/generated/code/Magento/Cms/Controller/Index/Index/Interceptor.php(39): MagentoCmsControllerIndexIndexInterceptor->___callPlugins('dispatch', Array, Array)

22 /home/silverg6/public_html/vendor/magento/framework/App/FrontController.php(55): MagentoCmsControllerIndexIndexInterceptor->dispatch(Object(MagentoFrameworkAppRequestHttp))

23 /home/silverg6/public_html/vendor/magento/framework/Interception/Interceptor.php(58): MagentoFrameworkAppFrontController->dispatch(Object(MagentoFrameworkAppRequestHttp))

24 /home/silverg6/public_html/vendor/magento/framework/Interception/Interceptor.php(138): MagentoFrameworkAppFrontControllerInterceptor->___callParent('dispatch', Array)

25 /home/silverg6/public_html/vendor/magento/module-store/App/FrontController/Plugin/RequestPreprocessor.php(94): MagentoFrameworkAppFrontControllerInterceptor->MagentoFrameworkInterception{closure}(Object(MagentoFrameworkAppRequestHttp))

26 /home/silverg6/public_html/vendor/magento/framework/Interception/Interceptor.php(135): MagentoStoreAppFrontControllerPluginRequestPreprocessor->aroundDispatch(Object(MagentoFrameworkAppFrontControllerInterceptor), Object(Closure), Object(MagentoFrameworkAppRequestHttp))

27 /home/silverg6/public_html/vendor/magento/module-page-cache/Model/App/FrontController/BuiltinPlugin.php(73): MagentoFrameworkAppFrontControllerInterceptor->MagentoFrameworkInterception{closure}(Object(MagentoFrameworkAppRequestHttp))

28 /home/silverg6/public_html/vendor/magento/framework/Interception/Interceptor.php(135): MagentoPageCacheModelAppFrontControllerBuiltinPlugin->aroundDispatch(Object(MagentoFrameworkAppFrontControllerInterceptor), Object(Closure), Object(MagentoFrameworkAppRequestHttp))

29 /home/silverg6/public_html/vendor/magento/framework/Interception/Interceptor.php(153): MagentoFrameworkAppFrontControllerInterceptor->MagentoFrameworkInterception{closure}(Object(MagentoFrameworkAppRequestHttp))

30 /home/silverg6/public_html/generated/code/Magento/Framework/App/FrontController/Interceptor.php(26): MagentoFrameworkAppFrontControllerInterceptor->___callPlugins('dispatch', Array, NULL)

31 /home/silverg6/public_html/vendor/magento/framework/App/Http.php(135): MagentoFrameworkAppFrontControllerInterceptor->dispatch(Object(MagentoFrameworkAppRequestHttp))

32 /home/silverg6/public_html/generated/code/Magento/Framework/App/Http/Interceptor.php(24): MagentoFrameworkAppHttp->launch()

33 /home/silverg6/public_html/vendor/magento/framework/App/Bootstrap.php(256): MagentoFrameworkAppHttpInterceptor->launch()

34 /home/silverg6/public_html/index.php(39): MagentoFrameworkAppBootstrap->run(Object(MagentoFrameworkAppHttpInterceptor))

35 {main}

.

@NagamaniNaresh run command to find all files with the element body and remove

It's not good best practice wise but you can bypass the validation by modifying this.
protected function _initDom($xml) line 382 of vendor/magento/framework/Config/Dom.php

        +// Note: Ignore validations. Yes the errors/warnings should be fixed but I don't know where to fix them and just want to get things done, can fix up "Later... TM".
        +$skipDomValidation = true;
        +if ($skipDomValidation === false) {
            if ($this->validationState->isValidationRequired() && $this->schema) {
                $errors = $this->validateDomDocument($dom, $this->schema, $this->errorFormat);
                if (count($errors)) {
                    throw new \Magento\Framework\Config\Dom\ValidationException(implode("\n", $errors));
                }
            }
        +}

@LiamKarlMitchell thank you. Saved my sanity.

Beside the fact that this is not a real bug, the error message is not helpful enough. It should state at least the file where the problem occurs imo.

@teamtaheny1 Actually, I was able to modify the method to have it spit out the last $dom prior to erroring.
Then I was able to grep in all php files for it part of it to find the problem lines that needed fixing.

grep -r --include=*.php "Some identifier of use to track it down" /var/www/mysite

There was a move element tag somewhere that was unexpected.
Yet it works fine if I skip validation...

To get more info that might help resolve this by identifying the file at fault.

Edit vendor/magento/framework/Config/Dom.php
Or it might be lib/internal/Magento/Framework/Config/Dom.php depending on your installation of Magento.

Find the public function _initDom($xml)

And add something like this before the normal validation check.

$verboseOutput = true;
if ($verboseOutput) {
  if ($this->validationState->isValidationRequired() && $this->schema) {
      $errors = $this->validateDomDocument($dom, $this->schema, $this->errorFormat);
      if (count($errors)) {
          var_dump($errors);

          $matches = [];
          preg_match("/Line: (\\d+)/", $errors[count($errors)-1], $matches);
          $lineNumber = intval($matches[1]);
          $lines = explode("\n", $xml);

          echo "<h1>A validation error occured in an XML layout file</h1>";
          $lineText = htmlentities($lines[$lineNumber-1]);
          echo $lineText . "<br>";

          echo "<pre>";
          echo "grep -rnw ./app -e " . escapeshellarg(trim($lineText));
          echo "</pre>";

          die('Please grep or search files for the above and fix it as per Magento 2 validation.');
      }
  }
}

Turn it off / remove after you fix up the offending files.

The files I had to adjust in this case were for Alothemes Magiccart theme.
I would suspect they have a theme update I can or that this was a custom modification.

./app/design/frontend/Alothemes/default/Magiccart_Magicmenu/layout/default.xml:25:        <referenceBlock name="store.menu" ifconfig="magicmenu/topmenu/enabled">
./app/design/frontend/Alothemes/demo2/Magiccart_Magicmenu/layout/default.xml:24:        <referenceBlock name="store.menu" ifconfig="magicmenu/topmenu/enabled">

There was also a move tag inside a block tag which was unexpected. (Although it functioned fine with validation off). Again not sure if this was custom code or in the theme.

./app/design/frontend/Alothemes/default/Magento_Theme/layout/default.xml

                <referenceContainer name="footer-container">
            <referenceBlock name="store_switcher" remove="true"/>
            <block class="Magento\Theme\Block\Html\Footer" name="alo.footer" template="html/footer.phtml">
                <block class="Magento\Cms\Block\Block" name="main-footer">
                    <arguments>
                        <argument name="block_id" xsi:type="string">cms-static-main-footer</argument>
                    </arguments>
                </block>
<!--                <move element="copyright" destination="alo.footer"/> Was here but I moved it below-->
            </block>
        </referenceContainer>

        <move element="copyright" destination="alo.footer"/>

Remember to flush your server caches.

bin/magento cache:flush

It's not good best practice wise but you can bypass the validation by modifying this.
protected function _initDom($xml) line 382 of vendor/magento/framework/Config/Dom.php

        +// Note: Ignore validations. Yes the errors/warnings should be fixed but I don't know where to fix them and just want to get things done, can fix up "Later... TM".
        +$skipDomValidation = true;
        +if ($skipDomValidation === false) {
            if ($this->validationState->isValidationRequired() && $this->schema) {
                $errors = $this->validateDomDocument($dom, $this->schema, $this->errorFormat);
                if (count($errors)) {
                    throw new \Magento\Framework\Config\Dom\ValidationException(implode("\n", $errors));
                }
            }
        +}

This subdues the original exception error message and now i'm left with a new one.

1 exception(s):
Exception #0 (InvalidArgumentException): Value for key "xsi:type" is missing in the argument data.

/chroot/home/m2.staging/html/vendor/magento/framework/View/Layout/Reader/Block.php(370): Magento\Framework\Data\Argument\Interpreter\Composite->evaluate(Array)
#1 /chroot/home/m2.staging/html/vendor/magento/framework/View/Layout/Reader/Block.php(169): Magento\Framework\View\Layout\Reader\Block->evaluateArguments(Object(Magento\Framework\View\Layout\Element), Array)

Any idea an easy way to fix this problem?

$verboseOutput = true; if ($verboseOutput) { if ($this->validationState->isValidationRequired() && $this->schema) { $errors = $this->validateDomDocument($dom, $this->schema, $this->errorFormat); if (count($errors)) { var_dump($errors); $matches = []; preg_match("/Line: (\d+)/", $errors[count($errors)-1], $matches); $lineNumber = intval($matches[1]); $lines = explode("n", $xml); echo "

A validation error occured in an XML layout file

"; $lineText = htmlentities($lines[$lineNumber-1]); echo $lineText . "
"; echo "
"; echo "grep -rnw ./app -e " . escapeshellarg(trim($lineText)); echo "
"; die('Please grep or search files for the above and fix it as per Magento 2 validation.'); } } }

I used this code and it was brilliant... it pointed me to here.. but i don't happen to see anything wrong with this block.. do you?

<?xml version="1.0"?> <body> <referenceContainer name="content"> <block class="Magento\Cms\Block\Block" name="gbp_success_page-block"> <arguments> <argument name="block_id" xsi:type="string">gbp_success_page</argument> </arguments> </block> </referenceContainer> </body>

       <container name="gbp-fullwidth-hero-wrapper" as="heroWrapper" label="Hero Wrapper" htmlTag="div" htmlClass="gbp-fullwidth-hero-wrapper" before="main.content">
          <block class="Magento\Cms\Block\Block" name="gbp-fullwidth-hero-block" ifconfig="theme/general/enable_fullwidth_hero">
            <arguments>
                <argument name="block_id" xsi:type="string">gbp_fullwidth_hero</argument>
            </arguments>
          </block>
        </container>

It's not good best practice wise but you can bypass the validation by modifying this.
protected function _initDom($xml) line 382 of vendor/magento/framework/Config/Dom.php

        +// Note: Ignore validations. Yes the errors/warnings should be fixed but I don't know where to fix them and just want to get things done, can fix up "Later... TM".
        +$skipDomValidation = true;
        +if ($skipDomValidation === false) {
            if ($this->validationState->isValidationRequired() && $this->schema) {
                $errors = $this->validateDomDocument($dom, $this->schema, $this->errorFormat);
                if (count($errors)) {
                    throw new \Magento\Framework\Config\Dom\ValidationException(implode("\n", $errors));
                }
            }
        +}

The issue fixed using this solution, but do changes in vendors file is not a good practice. So we should look for another solution.

It just needs to have better error message for developer to debug what is wrong... It should tell the filepath and line number at least.

I'm getting this because of theme have <script>jQuery.noConflict();</script> on \app\design\frontend\xxxx\xxxxx\Magento_Theme\layout\default_head_blocks.xml
There is no way to remove this or use src on it becoz theme functions depend on this and need to load extract current location on head,
i already fixed by remove validations of DOM xml, is that way good or is there have another way to add above in extract same location without override validations

You can add it to your "header.phtml" possibly in the theme.
The scripts in default head blocks just includes scripts if I remember right?

There is a head html thing in the admin design area that you can embed script.
If you use requirejs correctly you can require a specific version of jQuery for your theme/module files?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

punkstar picture punkstar  路  3Comments

PushEngineering picture PushEngineering  路  3Comments

kirashet666 picture kirashet666  路  3Comments

denis-g picture denis-g  路  3Comments

andreaskoch picture andreaskoch  路  3Comments